Fondamentalement, l'utilisation d'une boucle pour parcourir le ArrayList
est la seule option:
N'UTILISEZ PAS ce code, continuez à lire au bas de cette réponse pour voir pourquoi il n'est pas souhaitable et quel code devrait être utilisé à la place:
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);
En fait, une concaténation de chaînes va être très bien, car le javac
compilateur optimisera la concaténation de chaînes comme une série d' append
opérations de StringBuilder
toute façon. Voici une partie du démontage du bytecode de la for
boucle du programme ci-dessus:
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;
Comme on peut le voir, le compilateur optimise cette boucle en utilisant un StringBuilder
, donc les performances ne devraient pas être un gros problème.
(OK, au deuxième coup d'œil, l' StringBuilder
instanciation est effectuée à chaque itération de la boucle, donc ce n'est peut-être pas le bytecode le plus efficace. L'instanciation et l'utilisation d'un explicite StringBuilder
donneraient probablement de meilleures performances.)
En fait, je pense qu'avoir n'importe quelle sorte de sortie (que ce soit sur le disque ou sur l'écran) sera au moins un ordre de grandeur plus lent que d'avoir à se soucier des performances des concaténations de chaînes.
Edit: Comme indiqué dans les commentaires, l'optimisation du compilateur ci-dessus crée en effet une nouvelle instance de StringBuilder
à chaque itération. (Ce que j'ai noté précédemment.)
La technique la plus optimisée à utiliser sera la réponse de Paul Tomblin , car elle instancie uniquement un seul StringBuilder
objet en dehors de la for
boucle.
Réécriture dans le code ci-dessus pour:
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());
N'instanciera qu'une seule StringBuilder
fois à l'extérieur de la boucle, et ne fera que les deux appels à la append
méthode à l'intérieur de la boucle, comme en témoigne ce bytecode (qui montre l'instanciation de StringBuilder
et la boucle):
// 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
Ainsi, l'optimisation de la main devrait en effet être plus performante, car l'intérieur de la for
boucle est plus court et il n'est pas nécessaire d'instancier un StringBuilder
à chaque itération.