Plus précisément: StringBuffer pour jdk1.4 et inférieur, StringBuilder pour jdk1.5 et ultérieur, puisque ce dernier n'est pas synchronisé, donc un peu plus rapide.
VonC
2
Au lieu de deux invocations iter.hasNext (), j'ajoute habituellement un delimeter puis "retourne buf.substring (0, buf.length () - delimeter.length ())".
Vilmantas Baranauskas
2
Vous pouvez le rationaliser un peu en quittant tôt pour éviter le délimiteur: while (true) (add_iter; if (! Iter.hasNext ()) break; add_delim;}
À partir de Java 8, join()est désormais disponible sous forme de deux méthodes de classe sur la classe String. Dans les deux cas, le premier argument est le délimiteur.
En ce qui concerne la jointure, je pense que cela peut sembler un peu moins compliqué:
publicStringjoin(Collection<String> c){StringBuilder sb=newStringBuilder();for(String s: c)
sb.append(s);return sb.toString();}
Je ne peux pas utiliser la syntaxe Java 5 autant que je le voudrais (croyez-le ou non, j'utilise 1.0.x ces derniers temps), donc je suis peut-être un peu rouillé, mais je suis sûr que le concept est correct .
modifier l'ajout: les ajouts de chaînes peuvent être lents, mais si vous travaillez sur du code GUI ou sur une routine de courte durée, peu importe que vous preniez .005 secondes ou .006, donc si vous aviez une collection appelée "joinMe" que vous souhaitez ajouter à une chaîne existante "cible", il ne serait pas horrible de simplement insérer ceci:
for(String s : joinMe)
target += s;
C'est assez inefficace (et une mauvaise habitude), mais vous ne pourrez rien percevoir à moins qu'il y ait des milliers de chaînes ou que ce soit à l'intérieur d'une énorme boucle ou que votre code soit vraiment critique pour les performances.
Plus important encore, il est facile à retenir, court, rapide et très lisible. La performance n'est pas toujours le gagnant automatique dans les choix de conception.
La boucle for est correcte, mais vous devez également en faire une Collection <String>. Si vous ne le faites pas, vous devez dire "for (Object o: c)", car vous ne pouvez pas garantir que tout dans c était une chaîne.
Michael Myers
Bon point, je suis encore plus rouillé avec les génériques. Je vais le modifier.
Bill K
Lors de la concaténation en ligne: chaîne + chaîne + chaîne, le compilateur utilise en fait StringBuilder pour ajouter les valeurs. Je me demande si dans la méthode de la boucle for, vous avez le second, si le compilateur ferait de même.
Spencer Kormos
@Spencer K: Il utilise un StringBuilder, mais il en crée un nouveau pour chaque itération (ce n'est pas la méthode la plus efficace, mais alors comment le compilateur est-il censé savoir?). Je ne sais pas si le compilateur JIT pourrait optimiser cela au moment de l'exécution.
Michael Myers
2
Oh, attendez. Parlez-vous + =? Ouais, ça craint. La boucle et l'ajout actuellement dans ma réponse utilisent StringBuilder et c'est ce dont je parle. Bien que + = se soit beaucoup amélioré, vous ne voulez vraiment pas l'utiliser dans une boucle - pas tant qu'il est bogué mais qu'il peut fonctionner comme de la merde (Bug n'est pas un terme généralement utilisé pour les problèmes de performance - du moins pas dans mes 20 ans de programmation). Le JIT peut également améliorer énormément cela - mais je ne me fierais pas à cela.
Bill K
4
Voici une réponse assez simple. Utilisez +=car il s'agit de moins de code et laissez l'optimiseur le convertir en un StringBuilderpour vous. En utilisant cette méthode, vous n'avez pas à faire de vérifications "is last" dans votre boucle (amélioration des performances) et vous n'avez pas à vous soucier de supprimer les délimiteurs à la fin.
Solution très élégante, n'impliquant pas de bibliothèques tierces!
Denis Itskovich
2
Je ne voulais pas importer une bibliothèque Apache entière pour ajouter une simple fonction de jointure, alors voici mon hack.
publicStringjoin(String delim,List<String> destinations){StringBuilder sb =newStringBuilder();int delimLength = delim.length();for(String s: destinations){
sb.append(s);
sb.append(delim);}// we have appended the delimiter to the end // in the previous for-loop. Let's now remove it.if(sb.length()>= delimLength){return sb.substring(0, sb.length()- delimLength);}else{return sb.toString();}}
@MrSnowflake Le générateur de chaînes standard a-t-il une méthode "removeCharAt (int index)" Il
n'apparaît
@NSjonas - oui, sa modification de ma réponse est fausse. Le removeCharAtn'existe pas, et la fonction entière ne renvoie plus de chaîne ... Cela résoudra ce problème.
Martin Konecny
pendant que vous y êtes ... cette solution actuelle lancera une "exception d'index hors limites si vous passez dans une liste vide"
NSjonas
fait une modification pour obtenir la bonne longueur si la délimitation est supérieure à 1 caractère. Correction d'un problème où vous coupiez le dernier caractère et non le premier comme vous en aviez vraiment besoin
NSjonas
Merci pour les commentaires. Actualisé.
Martin Konecny
1
Si vous souhaitez joindre (concaténer) plusieurs chaînes en une seule, vous devez utiliser un StringBuilder. C'est bien mieux que d'utiliser
for(String s : joinMe)
target += s;
Il existe également une légère amélioration des performances par rapport à StringBuffer, car StringBuilder n'utilise pas la synchronisation.
Pour une méthode utilitaire à usage général comme celle-ci, elle sera (éventuellement) appelée plusieurs fois dans de nombreuses situations, vous devez donc la rendre efficace et ne pas allouer de nombreux objets transitoires. Nous avons profilé de très nombreuses applications Java différentes et constatons presque toujours que la concaténation de chaînes et les allocations chaîne / char [] prennent beaucoup de temps / mémoire.
Notre collection réutilisable -> méthode de chaîne calcule d'abord la taille du résultat requis, puis crée un StringBuilder avec cette taille initiale; cela évite de doubler / copier inutilement le caractère interne [] utilisé lors de l'ajout de chaînes.
re: pré-calcul de la taille: quand cela fonctionne, c'est génial. Ce n'est pas toujours possible. Je me souviens avoir lu quelque part que doubler la taille de la mémoire tampon à chaque fois (ou vraiment multiplier par un facteur fixe) donne quelque chose comme la performance n log n, ce qui n'est pas vraiment si mauvais. Dans le cas général, l'alternative est de faire une liste de toutes les chaînes que vous prévoyez de concaténer. Si vous utilisez une ArrayList, vous devez copier à nouveau (à moins que vous ne connaissiez à l'avance la longueur de votre séquence) et si vous utilisez LinkedList, alors il utilise plus de ram et de garbage collection avec les objets de nœud. Parfois, vous ne pouvez pas gagner. Essayez!
Ian
Les exemples / demandes ci-dessus supposaient une collection ou un tableau ordonné de chaînes à rejoindre. De plus, en précalculant la taille, vous évitez les caractères inutilisés supplémentaires que la croissance interne du tableau char [] entraîne généralement.
Je vois beaucoup d'implémentations trop complexes de String.Join here. Si vous n'avez pas Java 1.8 et que vous ne souhaitez pas importer une nouvelle bibliothèque, l'implémentation ci-dessous devrait suffire.
publicStringjoin(Collection<String> col,String delim){StringBuilder sb =newStringBuilder();for(String s : col ){if( sb.length()!=0) sb.append(delim);
sb.append(s);}return sb.toString();}
Je ne sais pas à quelle partie de la question cela répond? Ce n'est pas un String.format sauf si vous prévoyez d'ajouter les bits de la chaîne bit par bit au tableau, et [1,0.92,3] n'est pas aussi polyvalent qu'une chaîne générique .join.
Omar Kooheji
-8
J'utiliserais simplement l'opérateur de concaténation de chaînes "+" pour joindre deux chaînes. s1 += s2;
Réponses:
L'objet Java String a une
format
méthode (à partir de 1.5), mais aucunejoin
méthode.Pour obtenir un tas de méthodes utilitaires String utiles qui ne sont pas déjà incluses, vous pouvez utiliser org.apache.commons.lang.StringUtils .
la source
String.join()
méthode.String.format . En ce qui concerne la jointure, vous devez écrire le vôtre:
Ce qui précède provient de http://snippets.dzone.com/posts/show/91
la source
Guava vient avec la
Joiner
classe .la source
À partir de Java 8,
join()
est désormais disponible sous forme de deux méthodes de classe sur la classe String. Dans les deux cas, le premier argument est le délimiteur.Vous pouvez transmettre des
CharSequence
s individuels comme arguments supplémentaires :Ou vous pouvez passer un
Iterable<? extends CharSequence>
:Java 8 ajoute également une nouvelle classe
StringJoiner
, que vous pouvez utiliser comme ceci:la source
TextUtils.join est disponible sur Android
la source
Vous pouvez également utiliser des arguments variables pour les chaînes comme suit:
la source
En ce qui concerne la jointure, je pense que cela peut sembler un peu moins compliqué:
Je ne peux pas utiliser la syntaxe Java 5 autant que je le voudrais (croyez-le ou non, j'utilise 1.0.x ces derniers temps), donc je suis peut-être un peu rouillé, mais je suis sûr que le concept est correct .
modifier l'ajout: les ajouts de chaînes peuvent être lents, mais si vous travaillez sur du code GUI ou sur une routine de courte durée, peu importe que vous preniez .005 secondes ou .006, donc si vous aviez une collection appelée "joinMe" que vous souhaitez ajouter à une chaîne existante "cible", il ne serait pas horrible de simplement insérer ceci:
C'est assez inefficace (et une mauvaise habitude), mais vous ne pourrez rien percevoir à moins qu'il y ait des milliers de chaînes ou que ce soit à l'intérieur d'une énorme boucle ou que votre code soit vraiment critique pour les performances.
Plus important encore, il est facile à retenir, court, rapide et très lisible. La performance n'est pas toujours le gagnant automatique dans les choix de conception.
la source
Voici une réponse assez simple. Utilisez
+=
car il s'agit de moins de code et laissez l'optimiseur le convertir en unStringBuilder
pour vous. En utilisant cette méthode, vous n'avez pas à faire de vérifications "is last" dans votre boucle (amélioration des performances) et vous n'avez pas à vous soucier de supprimer les délimiteurs à la fin.la source
Je ne voulais pas importer une bibliothèque Apache entière pour ajouter une simple fonction de jointure, alors voici mon hack.
la source
removeCharAt
n'existe pas, et la fonction entière ne renvoie plus de chaîne ... Cela résoudra ce problème.Si vous souhaitez joindre (concaténer) plusieurs chaînes en une seule, vous devez utiliser un StringBuilder. C'est bien mieux que d'utiliser
Il existe également une légère amélioration des performances par rapport à StringBuffer, car StringBuilder n'utilise pas la synchronisation.
Pour une méthode utilitaire à usage général comme celle-ci, elle sera (éventuellement) appelée plusieurs fois dans de nombreuses situations, vous devez donc la rendre efficace et ne pas allouer de nombreux objets transitoires. Nous avons profilé de très nombreuses applications Java différentes et constatons presque toujours que la concaténation de chaînes et les allocations chaîne / char [] prennent beaucoup de temps / mémoire.
Notre collection réutilisable -> méthode de chaîne calcule d'abord la taille du résultat requis, puis crée un StringBuilder avec cette taille initiale; cela évite de doubler / copier inutilement le caractère interne [] utilisé lors de l'ajout de chaînes.
la source
J'ai écrit propre:
mais
Collection
n'est pas pris en charge par JSP, donc pour la fonction de balise, j'ai écrit:et mettre au
.tld
dossier:et utilisez-le dans les fichiers JSP comme:
la source
StringUtils est une classe assez utile dans la bibliothèque Apache Commons Lang.
la source
Il y a
MessageFormat.format()
ce qui fonctionne comme celui de C #String.Format()
.la source
Je vois beaucoup d'implémentations trop complexes de String.Join here. Si vous n'avez pas Java 1.8 et que vous ne souhaitez pas importer une nouvelle bibliothèque, l'implémentation ci-dessous devrait suffire.
la source
Donc, fondamentalement, le String ntop stocke la valeur de la collection entière avec des séparateurs de virgule et des crochets.
la source
J'utiliserais simplement l'opérateur de concaténation de chaînes "+" pour joindre deux chaînes.
s1 += s2;
la source