661 votes

Java : convertir une Liste<String> en String join()d

JavaScript a Array.join()

js>["Bill","Bob","Steve"].join(" and ")
Bill and Bob and Steve

Est-ce que Java a quelque chose comme ça ? Je sais que je peux bricoler quelque chose moi-même avec StringBuilder :

static public String join(List<String> list, String conjunction)
{
   StringBuilder sb = new StringBuilder();
   boolean first = true;
   for (String item : list)
   {
      if (first)
         first = false;
      else
         sb.append(conjunction);
      sb.append(item);
   }
   return sb.toString();
}

mais il n'y a aucun intérêt à faire cela si quelque chose comme cela fait déjà partie du JDK.

1 votes

Voir aussi cette question pour listes

18 votes

Ce n'est pas strictement lié, mais Android dispose d'une fonction de jonction intégrée à la classe TextUtils : [developer.Android.com/reference/Android/text/](http://developer.android.com/reference/android/text/TextUtils.html#join(java.lang.CharSequence) , java.lang.Iterable)

17 votes

Java 8 dispose d'une String.join() méthode. Consultez cette réponse si vous utilisez Java 8 (ou une version plus récente). stackoverflow.com/a/22577565/1115554

857voto

micha Points 7756

Avec Java 8, vous pouvez le faire sans aucune bibliothèque tierce.

Si vous souhaitez rejoindre une collection de cordes, vous pouvez utiliser la nouvelle fonction String.join() méthode :

List<String> list = Arrays.asList("foo", "bar", "baz");
String joined = String.join(" and ", list); // "foo and bar and baz"

Si vous avez une collection d'un autre type que String, vous pouvez utiliser l'API Stream avec la fonction rejoindre le collecteur :

List<Person> list = Arrays.asList(
  new Person("John", "Smith"),
  new Person("Anna", "Martinez"),
  new Person("Paul", "Watson ")
);

String joinedFirstNames = list.stream()
  .map(Person::getFirstName)
  .collect(Collectors.joining(", ")); // "John, Anna, Paul"

El StringJoiner peut également être utile.

7 votes

Malheureusement, String.join n'accepte que les CharSequences et non comme on pourrait l'espérer les Objects. Je ne suis même pas sûr que ce soit nullsafe.

0 votes

@Marc assertThat(String.join(", ", Lists.newArrayList("1", null)), is("1, null"));

0 votes

StringJoiner est particulièrement utile si l'on veut joindre à quelque chose comme [a, b, c] y compris les accolades.

308voto

Cowan Points 17235

Toutes les références à Apache Commons sont très bien (et c'est ce que la plupart des gens utilisent) mais je pense que l'approche de l Goyave équivalent, Menuisier a une API beaucoup plus agréable.

Vous pouvez faire le cas de la jointure simple avec

Joiner.on(" and ").join(names)

mais aussi de traiter facilement les valeurs nulles :

Joiner.on(" and ").skipNulls().join(names);

ou

Joiner.on(" and ").useForNull("[unknown]").join(names);

et (suffisamment utile en ce qui me concerne pour l'utiliser de préférence à commons-lang), la possibilité de traiter les cartes :

Map<String, Integer> ages = .....;
String foo = Joiner.on(", ").withKeyValueSeparator(" is ").join(ages);
// Outputs:
// Bill is 25, Joe is 30, Betty is 35

ce qui est extrêmement utile pour le débogage, etc.

11 votes

Merci pour le plugin ! Notre Joiner vous donne aussi l'option d'ajouter directement à un Appendable (comme un StringBuilder, ou n'importe quel Writer) sans créer de chaînes intermédiaires, ce qui semble manquer à la bibliothèque Apache.

2 votes

C'est génial, mais pouvez-vous ajouter une fonction .useForLastSeparator() ou une méthode similaire ? De cette façon, vous pourriez obtenir quelque chose comme ", et " entre les deux derniers éléments seulement (avec ", " pour le reste).

2 votes

Oui, c'est sans danger pour les fils. Le seul état sauvegardé dans un joiner est l'objet separator (qui est final ). Tout ce que j'ai vu en Guava, où j'avais l'habitude d'utiliser un équivalent d'Apache Commons, était tellement mieux (c'est-à-dire plus propre, plus rapide, plus sûr et tout simplement plus robuste en général) en Guava, avec moins de défaillances de cas limites et de problèmes de sécurité des threads et une empreinte mémoire plus petite. Leur principe directeur "la meilleure façon possible" semble se vérifier jusqu'à présent.

142voto

Arne Burmeister Points 8423

Pas dans la boîte, mais de nombreuses bibliothèques en ont de semblables :

Langue commune :

org.apache.commons.lang.StringUtils.join(list, conjunction);

Le printemps :

org.springframework.util.StringUtils.collectionToDelimitedString(list, conjunction);

49voto

Bart Kiers Points 79069

Non, il n'existe pas de méthode pratique de ce type dans l'API Java standard.

Il n'est pas surprenant que Apache Commons fournisse une telle chose dans leur classe StringUtils au cas où vous ne voudriez pas l'écrire vous-même.

11 votes

Ça m'a toujours dérangé que String ait un split mais pas un join. D'une certaine manière, cela a du sens, mais c'est juste ennuyeux qu'il n'y ait pas au moins une méthode statique pour cela dans String.

4 votes

Je suis avec vous Bemrose. Au moins, ils nous ont donné un isEmpty() au lieu d'une méthode (statique) join() méthode dans String ... :rollseyes : :)

19voto

Juha Syrjälä Points 11475

Le code que vous avez est la bonne façon de faire si vous voulez utiliser le JDK sans aucune bibliothèque externe. Il n'y a pas de "one-liner" simple que vous pourriez utiliser dans JDK.

Si vous pouvez utiliser des librairies externes, je vous recommande de regarder dans org.apache.commons.lang.StringUtils dans la bibliothèque Apache Commons.

Un exemple d'utilisation :

List<String> list = Arrays.asList("Bill", "Bob", "Steve");
String joinedResult = StringUtils.join(list, " and ");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X