Temel olarak, ArrayListtek 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, javacderleyici dize birleştirmeyi yine de bir dizi appendişlem olarak optimize edeceğinden , bir dize birleştirmesi gayet iyi olacaktır StringBuilder. forYukarı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, StringBuilderdöngü her yinelemesinde somutlaştırılıyor, bu yüzden en verimli bayt kodu olmayabilir. Açık bir örnek oluşturmak ve kullanmak StringBuildermuhtemelen 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 StringBuilderher 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ü StringBuilderdışı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());
StringBuilderDöngünün dışında yalnızca bir kez örnek oluşturur ve appendbu bayt kodunda ( StringBuilderdö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 fordaha kısa olduğundan ve StringBuilderher bir yinelemede bir somutlaştırmaya gerek olmadığından, el optimizasyonu daha iyi performans göstermelidir .