J'ai un ArrayList que je veux produire complètement en tant que chaîne. Essentiellement je veux le sortir dans l'ordre en utilisant le toString de chaque élément séparé par des tabulations. Y a-t-il un moyen rapide de le faire? Vous pouvez passer en boucle (ou supprimer chaque élément) et le concaténer à une chaîne mais je pense que ce sera très lent.
Réponses
Trop de publicités? Si vous faites cela sur Android, il y a un bon utilitaire pour ce TextUtils qui a une méthode .join(String delimiter, Iterable)
.
List<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);
Évidemment pas beaucoup d'utilisation en dehors d'Android, mais figuré je l'ajouterais à ce fil ...
Fondamentalement, l'aide d'une boucle pour parcourir l' ArrayList
est la seule option:
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îne est va être très bien, comme l' javac
compilateur d'optimiser la concaténation de chaîne comme une série d' append
des opérations sur un StringBuilder
de toute façon. Voici une partie du démontage du bytecode de l' for
boucle à partir 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 en boucle à l'aide d'un StringBuilder
, de sorte que les performances ne devraient pas être une grande préoccupation.
(OK, sur le deuxième coup d'œil, l' StringBuilder
est instancié à chaque itération de la boucle, de sorte qu'il peut ne pas être le plus efficace du bytecode. L'instanciation et l'utilisation explicite StringBuilder
produirait probablement de meilleures performances.)
En fait, je pense que le fait d'avoir toute sorte de sortie (que ce soit sur disque ou sur l'écran) sera d'au moins un ordre de grandeur plus lent que d'avoir à vous soucier de la performance de la chaîne de concaténations.
Edit: Comme l'a souligné dans les commentaires, ci-dessus optimisation du compilateur est en effet la création d'une nouvelle instance de l' StringBuilder
à chaque itération. (Que j'ai mentionné précédemment.)
Le plus optimisé la technique à utiliser sera la réponse de Paul Tomblin, car elle ne s'instancie un StringBuilder
objet en dehors de l' for
boucle.
La réécriture pour le code ci-dessus:
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());
Ne instancier l' StringBuilder
une fois à l'extérieur de la boucle, et de faire les deux appels à la append
méthode à l'intérieur de la boucle, comme en témoigne cette bytecode (qui montre l'instanciation d' 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
Donc, en effet la main d'optimisation devrait être plus performants, comme l'intérieur de l' for
boucle est plus court et il n'est pas nécessaire d'instancier un StringBuilder
à chaque itération.
Téléchargez le Jakarta Commons Lang et utilisez la méthode
StringUtils.join(list)
Vous pouvez l'implémenter vous-même, bien sûr, mais leur code est entièrement testé et est probablement la meilleure implémentation possible.
Je suis un grand fan de la bibliothèque de Jakarta Commons et je pense aussi que c'est un excellent ajout à la Java Standard Library.