Básicamente, usar un bucle para iterar sobre ArrayListes 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 javaccompilador optimizará la concatenación de cadenas como una serie de appendoperaciones de StringBuildertodos modos. Aquí hay una parte del desmontaje del bytecode del forbucle 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, StringBuilderse 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 StringBuilderprobablemente 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 StringBuildercada 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 StringBuilderobjeto fuera del forbucle.
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á StringBuilderuna instancia fuera del bucle y solo realizará las dos llamadas al appendmétodo dentro del bucle, como se evidencia en este código de bytes (que muestra la instanciación StringBuildery 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 forbucle es más corto y no hay necesidad de crear una instancia StringBuilderen cada iteración.