J'ai un ArrayList
que je veux sortir complètement sous forme de chaîne. Essentiellement, je veux le sortir dans l'ordre en utilisant le toString
de chaque élément séparé par des tabulations. Existe-t-il un moyen rapide de procéder? Vous pouvez le parcourir (ou supprimer chaque élément) et le concaténer en une chaîne, mais je pense que ce sera très lent.
353
Réponses:
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:
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 deStringBuilder
toute façon. Voici une partie du démontage du bytecode de lafor
boucle du programme ci-dessus: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 expliciteStringBuilder
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 lafor
boucle.Réécriture dans le code ci-dessus pour:
N'instanciera qu'une seule
StringBuilder
fois à l'extérieur de la boucle, et ne fera que les deux appels à laappend
méthode à l'intérieur de la boucle, comme en témoigne ce bytecode (qui montre l'instanciation deStringBuilder
et la boucle):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 unStringBuilder
à chaque itération.la source
Java
ou Geewax pourAndroid
Dans Java 8 ou version ultérieure:
Dans le cas où le
list
n'est pas de type String, un collecteur de jointure peut être utilisé:la source
S'il vous arrive de le faire sur Android, il existe un bel utilitaire pour cela appelé TextUtils qui a une
.join(String delimiter, Iterable)
méthode.Évidemment, pas beaucoup d'utilisation en dehors d'Android, mais je pensais l'ajouter à ce fil ...
la source
TextUtils.join
prend unObject[]
, je suppose qu'il fait appeltoString()
à chaque jeton. Met enPatientDetails
œuvretoString()
? Si cela ne résout pas le problème, vous pourriez être coincé à faire quelque chose avec laSeparator
classe.org.apache.lang3.StringUtils
fait pratiquement la même chose, donc votre réponse m'a été d'une grande utilité en dehors d'Android :)Téléchargez le langage Apache Commons et utilisez la méthode
Vous pouvez l'implémenter par 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 Apache Commons et je pense aussi que c'est un excellent ajout à la bibliothèque standard Java.
la source
StringUtils.join(list.toArray(),"\t")
C'est une question assez ancienne, mais je pense que je pourrais aussi bien ajouter une réponse plus moderne - utilisez la
Joiner
classe de Guava :la source
Changer la liste en une chaîne lisible et significative est vraiment une question courante que chacun peut rencontrer.
Cas 1 . Si vous avez StringUtils d'Apache dans votre chemin de classe (comme de rogerdpack et Ravi Wallau):
Cas 2 . Si vous ne souhaitez utiliser que les moyens de JDK (7):
Ne construisez jamais de roues vous-même, n'utilisez pas de boucle pour cette tâche en ligne.
la source
Arrays.toString(myList.toArray())
- la solution la plus simple et la plus simpleArrays.toString(list.toArray())
est facile à écrire, mais très inefficace.Si vous cherchiez un one-liner rapide, à partir de Java 5 vous pouvez le faire:
De plus, si votre but est simplement d'imprimer le contenu et que vous vous souciez moins du "\ t", vous pouvez simplement faire ceci:
qui renvoie une chaîne comme
Si vous avez un tableau (pas ArrayList), vous pouvez accomplir la même chose comme ceci:
la source
m
ménages desn
villes desx
États, vous diriez que c'estO(mnx)
ouO(n^3)
, mais je peux la reformuler pour dire "recherchez cette personne dans ce pays", et vous me diriez immédiatementO(n)
. En plus de cela, tous les algorithmes ici sont généralementO(n)
, il n'y a pas de boucle dans une boucle.Parcourez-le et appelez toString. Il n'y a pas de moyen magique, et s'il y en avait, que pensez-vous qu'il ferait sous les couvertures à part le boucler? La seule micro-optimisation serait d'utiliser StringBuilder au lieu de String, et même ce n'est pas une énorme victoire - concaténer des chaînes se transforme en StringBuilder sous les couvertures, mais au moins si vous l'écrivez de cette façon, vous pouvez voir ce qui se passe.
la source
La plupart des projets Java ont souvent une langue apache-commons disponible. Les méthodes StringUtils.join () sont très agréables et ont plusieurs saveurs pour répondre à presque tous les besoins.
la source
join(...)
méthode a des variantes pour les tableaux et les collections.Android a une classe TextUtil que vous pouvez utiliser http://developer.android.com/reference/android/text/TextUtils.html
la source
Pour ce cas d'utilisation simple, vous pouvez simplement joindre les chaînes avec une virgule. Si vous utilisez Java 8:
sinon commons-lang a une méthode join ():
la source
Une manière élégante de gérer les caractères de séparation de fin consiste à utiliser le séparateur de classes
La méthode toString de Class Separator renvoie le séparateur, sauf pour le premier appel. Ainsi, nous imprimons la liste sans traîner (ou dans ce cas) les séparateurs principaux.
la source
En Java 8, c'est simple. Voir l'exemple pour la liste des entiers:
Ou version multiligne (qui est plus simple à lire):
Mise à jour - une version plus courte
la source
filter
. Au final, il m'est beaucoup plus facile de lire le code.String
également. Si c'est une liste deInteger
s, vous avez un problèmeC'est un
O(n)
algorithme de toute façon (sauf si vous avez fait une solution multi-thread où vous avez divisé la liste en plusieurs sous-listes, mais je ne pense pas que c'est ce que vous demandez).Utilisez simplement un
StringBuilder
comme ci-dessous:Le
StringBuilder
sera beaucoup plus rapide que la concaténation de chaînes car vous ne réinstancierez pas unString
objet à chaque concaténation.la source
Dans le cas où vous vous trouvez sur Android et que vous n'utilisez pas encore Jack (par exemple, car il manque toujours de support pour Instant Run), et si vous voulez plus de contrôle sur le formatage de la chaîne résultante (par exemple, vous souhaitez utiliser le caractère de nouvelle ligne comme le diviseur d'éléments), et d'utiliser / vouloir utiliser la bibliothèque StreamSupport (pour utiliser des flux sur Java 7 ou des versions antérieures du compilateur), vous pouvez utiliser quelque chose comme ça (je mets cette méthode dans ma classe ListUtils):
Et bien sûr, assurez-vous d'implémenter toString () sur la classe des objets de votre liste.
la source
reduce
est extrêmement inefficace pour la concaténation de chaînes. Vous devez le faire de la manière Java 8return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))
qui utilise en interneStringJoiner
. Il n'y a aucune raison que vous ne puissiez pas faire cela avec streamsupport également.Optional#get
) s'il obtient une liste vide.Si vous ne voulez pas le dernier \ t après le dernier élément, vous devez utiliser l'index pour vérifier, mais n'oubliez pas que cela ne "fonctionne" (c'est-à-dire O (n)) que lorsque listes implémente RandomAccess.
la source
Le code ci-dessous peut vous aider,
Production:
la source
Peut-être pas la meilleure façon, mais élégante.
Arrays.deepToString (Arrays.asList ("Test", "Test2")
Production
[Test, Test2]
la source
Est-ce que ce qui suit serait bon:
la source
Si vous utilisez des collections Eclipse , vous pouvez utiliser la
makeString()
méthode.Si vous pouvez convertir votre
ArrayList
en unFastList
, vous pouvez vous débarrasser de l'adaptateur.Remarque: je suis un committer pour les collections Eclipse.
la source
Vous passez à la
new StringJoiner
séquence de caractères que vous souhaitez utiliser comme séparateur. Si vous voulez faire un CSV:new StringJoiner(", ");
la source
En une ligne: de [12,0,1,78,12] à 12 0 1 78 12
la source
Pour séparer en utilisant des onglets au lieu d'utiliser println, vous pouvez utiliser print
la source
Je vois pas mal d'exemples qui dépendent de ressources supplémentaires, mais il semble que ce serait la solution la plus simple: (qui est ce que j'ai utilisé dans mon propre projet) qui consiste simplement à convertir une ArrayList en une Array puis en une List .
la source
Il s'agit maintenant d'une conversation assez ancienne et apache commons utilise désormais un StringBuilder en interne: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line. 3045
Comme nous le savons, cela améliorera les performances, mais si les performances sont critiques, la méthode utilisée pourrait être quelque peu inefficace. Alors que l'interface est flexible et permettra un comportement cohérent entre les différents types de collections, elle est quelque peu inefficace pour les listes, qui est le type de collection dans la question d'origine.
Je base cela en ce que nous encourons des frais généraux que nous éviterions en parcourant simplement les éléments dans une boucle for traditionnelle. Au lieu de cela, il y a des choses supplémentaires qui se produisent en arrière-plan pour vérifier les modifications simultanées, les appels de méthode, etc. La boucle for améliorée entraînera en revanche la même surcharge puisque l'itérateur est utilisé sur l'objet Iterable (la liste).
la source
Vous pouvez utiliser un Regex pour cela. C'est aussi concis que possible
la source
Que diriez-vous de cette fonction:
ça marche pour tout type de collection ...
la source