Fondamentalmente, l'uso di un ciclo per scorrere l'iter ArrayListè l'unica opzione:
NON utilizzare questo codice, continua a leggere fino alla fine di questa risposta per vedere perché non è desiderabile e quale codice dovrebbe essere utilizzato invece:
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);
In effetti, una concatenazione di stringhe andrà bene, dato che il javaccompilatore ottimizzerà la concatenazione di stringhe come una serie di appendoperazioni su un StringBuildercomunque. Ecco una parte dello smontaggio del bytecode dal forloop dal programma sopra:
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;
Come si può vedere, il compilatore ottimizza quel loop usando un StringBuilder, quindi le prestazioni non dovrebbero essere una grande preoccupazione.
(OK, a un secondo sguardo, StringBuilderviene istanziato su ogni iterazione del loop, quindi potrebbe non essere il bytecode più efficiente. L'istanza e l'uso di un esplicito StringBuilderprobabilmente produrrebbe prestazioni migliori.)
In effetti, penso che avere qualsiasi tipo di output (sia esso su disco o sullo schermo) sarà almeno di un ordine di grandezza più lento rispetto a doversi preoccupare delle prestazioni delle concatenazioni di stringhe.
Modifica: come sottolineato nei commenti, l'ottimizzazione del compilatore sopra sta effettivamente creando una nuova istanza di StringBuilderogni iterazione. (Che ho notato in precedenza.)
La tecnica più ottimizzata da utilizzare sarà la risposta di Paul Tomblin , in quanto crea un'istanza di un singolo StringBuilderoggetto all'esterno del forloop.
Riscrivere il codice sopra per:
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());
Istituirà solo StringBuilderuna volta l'esterno del ciclo e effettuerà solo le due chiamate al appendmetodo all'interno del ciclo, come evidenziato in questo bytecode (che mostra l'istanza di StringBuildere il ciclo):
// 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
Quindi, in effetti l'ottimizzazione della mano dovrebbe essere più performante, poiché l'interno del forciclo è più breve e non è necessario creare un'istanza StringBuildersu ogni iterazione.