StringBuilder
Java'nın zaten String
eklemeye izin veren çok güçlü bir sınıfa sahip olması nedeniyle ilk kez karşılaştım ve şaşırdım .
Neden ikinci String
sınıf?
Daha fazla bilgiyi nereden öğrenebilirim StringBuilder
?
StringBuilder
Java'nın zaten String
eklemeye izin veren çok güçlü bir sınıfa sahip olması nedeniyle ilk kez karşılaştım ve şaşırdım .
Neden ikinci String
sınıf?
Daha fazla bilgiyi nereden öğrenebilirim StringBuilder
?
Yanıtlar:
String
eklemeye izin vermiyor. A'da çalıştırdığınız her yöntem String
yeni bir nesne oluşturur ve onu döndürür. Bunun nedeni String
değişmez olmasıdır - iç durumunu değiştiremez.
Öte yandan StringBuilder
değişebilir. Onu çağırdığınızda append(..)
, yeni bir dize nesnesi oluşturmak yerine dahili karakter dizisini değiştirir.
Bu nedenle şunlara sahip olmak daha etkilidir:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
sb.append(i);
}
yerine str += i
, 500 yeni dize nesnesi oluşturacaktır.
Örnekte bir döngü kullandığıma dikkat edin. Helios'un yorumlarda belirttiği gibi, derleyici benzer ifadeleri otomatik String d = a + b + c
olarak şöyle bir şeye çevirir:
String d = new StringBuilder(a).append(b).append(c).toString();
Ayrıca StringBuffer
ek olarak olduğunu unutmayın StringBuilder
. Aradaki fark, eskisinin senkronize yöntemlere sahip olmasıdır. Yerel değişken olarak kullanırsanız StringBuilder
,. Birden fazla iş parçacığı tarafından erişilmesi mümkünse, kullanın StringBuffer
(bu daha nadirdir)
İşte neden olduğuna dair somut bir örnek -
int total = 50000;
String s = "";
for (int i = 0; i < total; i++) { s += String.valueOf(i); }
// 4828ms
StringBuilder sb = new StringBuilder();
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); }
// 4ms
Gördüğünüz gibi performanstaki fark önemli.
s = sb.ToString();
en azından her iki örnekte de aynı şeyi yaptın (sonuç a string
).
String sınıfı değişmezken StringBuilder değiştirilebilir.
String s = "Hello";
s = s + "World";
Yukarıdaki kod iki nesne oluşturacak çünkü String değişmez
StringBuilder sb = new StringBuilder("Hello");
sb.append("World");
Yukarıdaki kod yalnızca bir nesne oluşturacaktır çünkü StringBuilder değişmez değildir.
Ders: String'i manipüle etme / güncelleme / ekleme ihtiyacı olduğunda, birçok kez StringBuilder, String'e kıyasla verimli olduğu için StringBuilder'a gidin.
StringBuilder, dizeler oluşturmak içindir. Özellikle, onları çok performanslı bir şekilde inşa etmek. String sınıfı birçok şey için iyidir, ancak aslında daha küçük dizgi parçalarından yeni bir dizi oluştururken gerçekten korkunç bir performansa sahiptir çünkü her yeni dizi tamamen yeni, yeniden tahsis edilmiş bir dizedir. ( Değişmezdir ) StringBuilder aynı sırayı yerinde tutar ve onu değiştirir ( değiştirilebilir ).
StringBuilder sınıfı değiştirilebilir ve String'den farklı olarak, daha fazla String nesnesi oluşturmanıza gerek kalmadan dizenin içeriğini değiştirmenize olanak tanır; bu, bir dizeyi yoğun bir şekilde değiştirirken bir performans kazanımı olabilir. Ayrıca StringBuilder için StringBuffer adında bir muadili vardır ve bu da senkronize edilir, bu nedenle çok iş parçacıklı ortamlar için idealdir.
String ile ilgili en büyük sorun, onunla yaptığınız herhangi bir işlemin her zaman yeni bir nesne döndürmesidir, örneğin:
String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
StringBuilder, daha büyük dizelerle uğraşırken iyidir. Performansı artırmanıza yardımcı olur.
İşte yararlı bulduğum bir makale .
Hızlı bir Google araması size yardımcı olabilirdi. Şimdi sizin için bir google araması yapması için 7 farklı kişiyi işe aldınız. :)
Kesin olmak gerekirse, StringBuilder tüm dizeleri eklerken O (N), String'ler ise O (N ^ 2). Kaynak kodunu kontrol ederek, bu dahili olarak değiştirilebilir bir karakter dizisi tutularak elde edilir. StringBuilder , gerekli belleği ikiye katlama pahasına ammortized O (N ^ 2) performansı elde etmek için dizi uzunluğu çoğaltma tekniğini kullanır . Bunu çözmek için sonunda trimToSize'ı çağırabilirsiniz, ancak genellikle StringBuilder nesneleri yalnızca geçici olarak kullanılır. Nihai dize boyutunda iyi bir başlangıç tahmini sağlayarak performansı daha da artırabilirsiniz.
Verimlilik.
Dizeleri her birleştirdiğinizde, yeni bir dize oluşturulacaktır. Örneğin:
String out = "a" + "b" + "c";
Bu yeni, geçici bir dize oluşturur, "a" ve "b" yi "ab" ile sonuçlanacak şekilde kopyalar. Sonra başka bir yeni, geçici dize oluşturur, "ab" ve "c" yi kopyalayarak "abc" ile sonuçlanır. Bu sonuç daha sonra atanır out
.
Sonuç, bir Schlemiel the Painter'ın O (n²) (ikinci dereceden) zaman karmaşıklığı algoritmasıdır .
StringBuilder
Diğer yandan, çıktı dizesini gerektiği gibi yeniden boyutlandırarak yerinde dizeler eklemenize olanak tanır.
Java'da String, StringBuffer ve StringBuilder vardır:
Dize: Değişmez
StringBuffer: Değişken ve ThreadSafe
StringBuilder: Değişken ama ThreadSafe Değil, Java 1.5 ile birlikte sunuldu
Dize, örneğin:
public class T1 {
public static void main(String[] args){
String s = "Hello";
for (int i=0;i<10;i++) {
s = s+"a";
System.out.println(s);
}
}
}
}
output: Sadece 1 String yerine 10 Farklı String oluşturulacaktır.
Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa
Helloaaaaaaaaa
Helloaaaaaaaaaa
StringBuilder örneğin: Yalnızca 1 StringBuilder nesnesi oluşturulacaktır.
public class T1 {
public static void main(String[] args){
StringBuilder s = new StringBuilder("Hello");
for (int i=0;i<10;i++) {
s.append("a");
System.out.println(s);
}
}
}