Básicamente, usar un bucle para iterar sobre ArrayList
es la única opción:
NO use este código, continúe leyendo hasta el final de esta respuesta para ver por qué no es deseable y qué código debe usarse en su lugar:
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);
De hecho, una concatenación de cadenas estará bien, ya que el javac
compilador optimizará la concatenación de cadenas como una serie de append
operaciones de StringBuilder
todos modos. Aquí hay una parte del desmontaje del bytecode del for
bucle del programa anterior:
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;
Como se puede ver, el compilador optimiza ese ciclo mediante el uso de a StringBuilder
, por lo que el rendimiento no debería ser una gran preocupación.
(OK, en una segunda mirada, StringBuilder
se está instanciando el en cada iteración del bucle, por lo que puede que no sea el código de bytes más eficiente. La creación de instancias y el uso de un explícito StringBuilder
probablemente produciría un mejor rendimiento).
De hecho, creo que tener cualquier tipo de salida (ya sea en el disco o en la pantalla) será al menos un orden de magnitud más lento que tener que preocuparse por el rendimiento de las concatenaciones de cadenas.
Editar: Como se señaló en los comentarios, la optimización del compilador anterior está creando una nueva instancia de StringBuilder
cada iteración. (Lo cual he notado anteriormente).
La técnica más optimizada para usar será la respuesta de Paul Tomblin , ya que solo crea una instancia de un StringBuilder
objeto fuera del for
bucle.
Reescribiendo el código anterior para:
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());
Solo creará StringBuilder
una instancia fuera del bucle y solo realizará las dos llamadas al append
método dentro del bucle, como se evidencia en este código de bytes (que muestra la instanciación StringBuilder
y el bucle):
// 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
Entonces, de hecho, la optimización de la mano debería tener un mejor rendimiento, ya que el interior del for
bucle es más corto y no hay necesidad de crear una instancia StringBuilder
en cada iteración.