Temel olarak, ArrayList
tek seçenek üzerinde bir döngü kullanmak tek seçenektir:
Bu kodu KULLANMAYIN, neden istenmediğini ve bunun yerine hangi kodun kullanılması gerektiğini görmek için bu cevabın altına okumaya devam edin:
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
String listString = "";
for (String s : list)
{
listString += s + "\t";
}
System.out.println(listString);
Aslında, javac
derleyici dize birleştirmeyi yine de bir dizi append
işlem olarak optimize edeceğinden , bir dize birleştirmesi gayet iyi olacaktır StringBuilder
. for
Yukarıdaki programdan bayt kodunun döngüden sökülmesinin bir kısmı :
61: new #13; //class java/lang/StringBuilder
64: dup
65: invokespecial #14; //Method java/lang/StringBuilder."<init>":()V
68: aload_2
69: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: aload 4
74: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
77: ldc #16; //String \t
79: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
82: invokevirtual #17; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
Görüldüğü gibi, derleyici bu döngüyü a kullanarak optimize eder StringBuilder
, bu nedenle performans büyük bir endişe olmamalıdır.
(Tamam, ikinci bakışta, StringBuilder
döngü her yinelemesinde somutlaştırılıyor, bu yüzden en verimli bayt kodu olmayabilir. Açık bir örnek oluşturmak ve kullanmak StringBuilder
muhtemelen daha iyi performans sağlar.)
Aslında, herhangi bir çıktıya sahip olmanın (diske veya ekrana) en azından dize birleşimlerinin performansı hakkında endişelenmekten daha yavaş bir büyüklük sırası olacağını düşünüyorum.
Düzenleme: Yorumlarda belirtildiği gibi, yukarıdaki derleyici optimizasyonu gerçekten de StringBuilder
her yinelemenin yeni bir örneğini yaratıyor . (Daha önce de belirttiğim gibi.)
Kullanılacak en optimize edilmiş teknik, Paul Tomblin'in yanıtıdır , çünkü sadece döngü StringBuilder
dışında tek bir nesneyi başlatır for
.
Yukarıdaki koda yeniden yazmak için:
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
StringBuilder sb = new StringBuilder();
for (String s : list)
{
sb.append(s);
sb.append("\t");
}
System.out.println(sb.toString());
StringBuilder
Döngünün dışında yalnızca bir kez örnek oluşturur ve append
bu bayt kodunda ( StringBuilder
döngünün örneğini ve döngüyü gösterir) gösterildiği gibi, döngü içindeki yönteme yalnızca iki çağrı yapar :
// Instantiation of the StringBuilder outside loop:
33: new #8; //class java/lang/StringBuilder
36: dup
37: invokespecial #9; //Method java/lang/StringBuilder."<init>":()V
40: astore_2
// [snip a few lines for initializing the loop]
// Loading the StringBuilder inside the loop, then append:
66: aload_2
67: aload 4
69: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: pop
73: aload_2
74: ldc #15; //String \t
76: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
79: pop
Bu nedenle, ilmenin içi for
daha kısa olduğundan ve StringBuilder
her bir yinelemede bir somutlaştırmaya gerek olmadığından, el optimizasyonu daha iyi performans göstermelidir .