Le meilleur moyen de convertir une liste de tableaux à une chaîne
J'ai un ArrayList
que je veux sortie complètement comme une Chaîne de caractères. Essentiellement, je veux de sortie dans l'ordre en utilisant les toString
de chaque élément étant séparé par des tabulations. Est-il un moyen rapide de faire cela? Vous pourriez faire une boucle par elle (ou supprimer chaque élément) et de concaténer une Chaîne, mais je pense que ce sera très lent.
- ou supprimer chaque élément attention, la suppression d'éléments à partir d'une liste de tableaux liste est un gros NO-NO, que votre "boucle" prendra quadratique du temps en raison du déplacement des éléments (à condition que vous la boucle du premier au dernier élément).
- De même pour les collections: stackoverflow.com/questions/395401/...
Vous devez vous connecter pour publier un commentaire.
Fondamentalement, à l'aide d'une boucle pour parcourir les
ArrayList
est la seule option:N'utilisez PAS ce code, continuer la lecture vers le bas de cette réponse de voir pourquoi il n'est pas souhaitable, et dont le code doit être utilisé à la place:
En fait, une concaténation de chaîne est va être très bien, comme le
javac
compilateur d'optimiser la concaténation de chaîne comme une série deappend
opérations sur unStringBuilder
de toute façon. Voici une partie du démontage du bytecode de lafor
boucle à partir du programme ci-dessus: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, le
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 expliciteStringBuilder
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
StringBuilder
à chaque itération. (Que j'ai mentionné précédemment.)Le plus optimisé la technique à utiliser sera la réponse par Paul Tomblin, car elle ne s'instancie un
StringBuilder
objet en dehors de lafor
boucle.Réécrire le code ci-dessus pour:
Ne instancier la
StringBuilder
une fois à l'extérieur de la boucle, et de faire les deux appels à laappend
méthode à l'intérieur de la boucle, comme en témoigne cette bytecode (qui montre l'instanciation deStringBuilder
et la boucle):Donc, en effet la main d'optimisation devrait être plus performants, comme l'intérieur de la
for
boucle est plus court et il n'est pas nécessaire d'instancier unStringBuilder
à chaque itération.Java
ou Geewax pourAndroid
Dans Java 8 ou version ultérieure:
Dans le cas où le
list
n'est pas de type Chaîne de caractères, un de rejoindre le collecteur peut être utilisé:Collectors.joining
), ce qui se passe si la liste est vide? Ne vous retourne une chaîne vide ou null?StringJoiner
ou laString.join
si l'ordre est nécessaire.S'il vous arrive de le faire sur Android, il y a une belle utilité pour cela appelé TextUtils qui a un
.join(String delimiter, Iterable)
méthode.Évidemment pas beaucoup l'utiliser en dehors d'Android, mais pensé que je voudrais ajouter à ce fil...
TextUtils.join
prend unObject[]
, je suppose qu'il appelletoString()
sur chaque jeton. NePatientDetails
mettre en œuvretoString()
? Si cela ne résout pas le problème, vous pouvez être coincé faire quelque chose avec laSeparator
classe.public static String join(CharSequence delimiter, Iterable tokens)
À l'aide de matières de ce type dans une nouvelle bibliothèque est vraiment un échec sur Google est à côté. Surtout quand il est facile de generified àpublic static <T> String join(CharSequence delimiter, Iterable<T> tokens)
.org.apache.lang3.StringUtils
n'y a pratiquement la même, de sorte que votre réponse est absolument d'une grande aide pour moi en dehors de Android 🙂org.apache.commons.lang3.StringUtils
. Vous avez manqué un "commons" il.Télécharger Apache Commons Lang et d'utiliser la méthode
Vous pouvez la mettre en œuvre par vous-même, bien sûr, mais leur code est entièrement testé et est probablement la meilleure application possible.
Je suis un grand fan de l'Apache Commons bibliothèque et je pense aussi que c'est un excellent ajout à la Norme Java Bibliothèque.
StringUtils.join(list.toArray(),"\t")
StringUtils.join(list, "\t")
.String.join(",", arrayList)
pour convertir la liste de tableaux dans une chaîne unique et l'utilisation séparateur pour séparer le tableau de valeurs de la liste. Pas besoin d'utiliser une autre bibliothèque. Et si vous ne voulez pas de délimiteur utilisationString.join("", arrayList);
String.join
a été ajoutée dans Java 8, il pourrait ne pas être disponibles dans votre environnement. par exemple, Android.C'est une jolie vieille question, mais je me dis que je pourrais bien ajouter un plus moderne réponse - utiliser le
Menuiserie
classe de Goyave:Changer Liste à un lisible et significative Chaîne est vraiment une question que chacun peut rencontrer.
Cas 1. Si vous avez apache StringUtils dans votre chemin de classe (à partir de rogerdpack et Ravi Wallau):
Cas 2 . Si vous souhaitez uniquement utiliser les moyens de JDK(7):
Jamais construire des roues par vous-même, ne pas utiliser de boucle pour celui-ci de la ligne de la tâche.
Arrays.toString(myList.toArray())
- la méthode la plus simple et la solution la plus simpleSi vous avez été la recherche d'un rapide one-liner, comme de Java 5, vous pouvez le faire:
En outre, si votre but est simplement d'imprimer le contenu et sont moins concernés par le "\t", vous pouvez simplement faire ceci:
qui retourne une chaîne de caractères comme
Si vous avez un Tableau (pas de liste de tableaux), alors vous pouvez faire la même chose comme ceci:
m
ménages dansn
villesx
unis, vous dirais que c'estO(mnx)
ouO(n^3)
, mais je peux la reformuler pour dire "regardez pour cette personne, dans ce pays," et vous serait immédiatement me direO(n)
. En plus de cela, tous les algorithmes ici sont généralementO(n)
, il n'y a pas de boucle dans une boucle.Boucle à travers elle et l'appeler toString. Il n'y a pas de solution magique, et si il y en avait, que pensez vous qu'il serait sous les couvertures autres que la boucle à travers elle? Sur le seul micro-optimisation serait d'utiliser StringBuilder au lieu de String, et ce n'est même pas un gain énorme - de la concaténation de chaînes se transforme en StringBuilder sous les couvertures, mais au moins si vous l'écrire de cette façon, vous pouvez voir ce qu'il se passe.
La plupart des projets Java ont souvent apache commons lang disponibles. StringUtils.join() méthodes est très agréable et dispose de plusieurs saveurs pour satisfaire presque tous les besoins.
join(...)
méthode a des variantes pour les deux tableaux et les collections.Android dispose d'un TextUtil classe, vous pouvez utiliser http://developer.android.com/reference/android/text/TextUtils.html
Une élégante façon de traiter avec fuite de la séparation des caractères est d'utiliser Classe Séparateur
La méthode toString de la Classe Séparateur renvoie la separater, sauf pour le premier appel. Nous avons donc l'impression de la liste sans fuite (ou dans ce cas), conduisant à des séparateurs.
Pour ce cas simple d'utilisation, vous pouvez simplement joindre les cordes avec des virgules. Si vous utilisez Java 8:
sinon commons-lang a une méthode join ():
ArrayList
classe (Java Docs) s'étendAbstractList
classe, qui s'étendAbstractCollection
classe qui contient unetoString()
méthode (Java Docs). Donc, il suffit d'écrireLes développeurs Java ont déjà trouvé le moyen le plus efficace, et vous ai donné que dans une, joliment emballé, et la méthode documentée. Simplement appeler cette méthode.
C'est un
O(n)
algorithme de toute façon (sauf si vous avez fait une partie multi-thread solution où vous avez cassé la liste en plusieurs sous-listes, mais je ne pense pas que c'est ce que vous demandez).Il suffit d'utiliser un
StringBuilder
comme ci-dessous:La
StringBuilder
sera beaucoup plus rapide que la concaténation de chaîne parce que vous ne sera pas ré-instancier unString
objet sur chaque concaténation.Dans le cas où vous arrive d'être sur Android, et vous n'êtes pas à l'aide de Jack encore (par exemple, parce que c'est encore un manque de soutien pour l'Instant de Lancer), 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 saut de ligne comme le séparateur d'éléments), et arriver à utiliser/vous désirez utiliser le StreamSupport bibliothèque (pour l'utilisation des cours d'eau sur Java 7 ou versions antérieures du compilateur), vous pouvez utiliser quelque chose comme ceci (j'ai mis cette méthode dans mon ListUtils classe):
Et bien sûr, assurez-vous de mettre en œuvre les méthodes toString() sur la liste des objets de la classe.
reduce
est extrêmement inefficace pour la concaténation de Chaîne. Vous devriez faire la Java 8return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))
qui utilise en interneStringJoiner
. Il n'y a aucune raison que vous ne pouvait pas le faire avec streamsupport aussi.Optional#get
) si celui-ci est transmis 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 "fonctionne" (c'est à dire O(n)) lorsque les listes implémente l'RandomAccess.
Le code ci-dessous peut vous aider,
De sortie:
Peut-être pas la meilleure façon, mais de manière élégante.
Tableaux.deepToString(Tableaux.asList("Test", "Test2")
Sortie
[Test Test2]
Suite être tout bon:
Si vous utilisez Eclipse Collections, vous pouvez utiliser le
makeString()
méthode.Si vous pouvez convertir votre
ArrayList
à unFastList
, vous pouvez vous débarrasser de l'adaptateur.Remarque: je suis un committer pour Eclipse Collections.
Vous passez à la
new StringJoiner
le char de la séquence que vous souhaitez être utilisé comme séparateur. Si vous voulez faire un CSV:new StringJoiner(", ");
Dans Java 8 c'est simple. Voir exemple de liste d'entiers:
Ou multiligne version (qui est plus simple à lire):
Mise à jour d'une version plus courte
filter
. En fin de compte, il est beaucoup plus facile pour moi de lire le code.String
ainsi. Si ses une liste deInteger
s vous avez un problèmePour les séparant à l'aide d'onglets au lieu d'utiliser println vous pouvez utiliser impression
Je voir quelques 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 projet) qui est fondamentalement juste la conversion à partir d'une liste de tableaux un Tableau et ensuite à une Liste.
C'est un assez vieux conversation en maintenant et apache commons sont maintenant à l'aide d'un StringBuilder en interne: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line.3045
Ce sera comme nous le savons améliorer les performances, mais si la performance est critique ensuite la méthode utilisée pourrait être quelque peu inefficace. Alors que l'interface est flexible et permettra constante de leur comportement à travers les différents types de Collection, il est quelque peu inefficace pour les Listes, qui est le type de Collecte dans la question d'origine.
Je me base que nous sommes encourir des frais généraux qui nous permettrait d'éviter simplement en parcourant les éléments traditionnels de la boucle. Au lieu de cela il y a certaines choses qui se passe derrière les coulisses de la vérification pour les modifications concurrentes, les appels de méthode etc. Le renforcement de boucle d'autre part de résultat dans les mêmes frais généraux depuis l'itérateur est utilisé sur l'objet Itérable (la Liste).
Vous pouvez utiliser une Regex pour cela. C'est aussi concis qu'il obtient
En une seule Ligne :
À partir de [12,0,1,78,12] 12 0 1 78 12
Comment à propos de cette fonction:
cela fonctionne pour n'importe quel type de collection...