Java: convertir la liste en chaîne de caractères

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 ça ne sert à rien de faire ça si quelque chose comme ça fait déjà partie du JDK.

471
demandé sur Ani Menon 2009-11-18 00:15:14

22 réponses

avec Java 8, Vous pouvez le faire sans bibliothèque tierce.

si vous voulez rejoindre une Collection de cordes, vous pouvez utiliser la nouvelle chaîne .join() la 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 avec un autre type de chaîne, vous pouvez utiliser L'API Stream avec le jointing Collector :

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"

la classe StringJoiner peut également être utile.

566
répondu micha 2014-10-09 07:07:30

toutes les références à Apache Commons sont bonnes (et c'est ce que la plupart des gens utilisent) mais je pense que le Goyave équivalent, Menuisier , a une API beaucoup plus agréable.

vous pouvez faire le cas simple join case avec

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

mais aussi facilement traiter avec nulls:

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

ou

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

et (assez utile en ce qui me concerne pour l'utiliser dans préférence à commons-lang), la capacité de traiter des cartes:

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

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

289
répondu Cowan 2016-07-15 21:54:21

Pas hors de la boîte, mais beaucoup de bibliothèques ont les mêmes:

Commons Lang:

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

le Printemps:

org.springframework.util.StringUtils.collectionToDelimitedString(list, conjunction);
130
répondu Arne Burmeister 2009-11-17 21:20:32

Sur Android , vous pourriez utiliser TextUtils de la classe.

TextUtils.join(" and ", names);
104
répondu Rafal Enden 2015-09-01 15:06:44

Non, il n'y a pas de méthode de ce genre dans L'API Java standard.

sans surprise, Apache Commons fournit une telle chose dans leur classe StringUtils au cas où vous ne voulez pas l'écrire vous-même.

47
répondu Bart Kiers 2013-07-22 08:51:09

trois possibilités en Java 8:

List<String> list = Arrays.asList("Alice", "Bob", "Charlie")

String result = String.join(" and ", list);

result = list.stream().collect(Collectors.joining(" and "));

result = list.stream().reduce((t, u) -> t + " and " + u).orElse("");
35
répondu amra 2015-08-26 09:34:30

avec un Java 8 collector, cela peut être fait avec le code suivant:

Arrays.asList("Bill", "Bob", "Steve").stream()
.collect(Collectors.joining(" and "));

aussi, la solution la plus simple en java 8:

String.join(" and ", "Bill", "Bob", "Steve");

ou

String.join(" and ", Arrays.asList("Bill", "Bob", "Steve"));
23
répondu aifa 2014-11-24 23:33:41

j'ai écrit celui-ci (je l'utilise pour les haricots et exploiter toString , alors n'écrivez pas Collection<String> ):

public static String join(Collection<?> col, String delim) {
    StringBuilder sb = new StringBuilder();
    Iterator<?> iter = col.iterator();
    if (iter.hasNext())
        sb.append(iter.next().toString());
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(iter.next().toString());
    }
    return sb.toString();
}

mais Collection n'est pas supporté par JSP, donc pour TLD j'ai écrit:

public static String join(List<?> list, String delim) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        sb.append(delim);
        sb.append(list.get(i).toString());
    }
    return sb.toString();
}

et mis à .tld dossier:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
    <function>
        <name>join</name>
        <function-class>com.core.util.ReportUtil</function-class>
        <function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
    </function>
</taglib>

et l'utiliser dans les fichiers JSP comme:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}
19
répondu gavenkoa 2013-04-05 15:08:29

Code que vous avez est la bonne façon de le faire si vous voulez utiliser JDK sans bibliothèques externes. Il n'y a pas de Simple "one-liner" que vous pourriez utiliser dans JDK.

si vous pouvez utiliser des libs externes, je vous recommande de regarder dans org.Apache.commun.lang.Classe StringUtils à la bibliothèque Apache.

exemple d'usage:

List<String> list = Arrays.asList("Bill", "Bob", "Steve");
String joinedResult = StringUtils.join(list, " and ");
16
répondu Juha Syrjälä 2009-11-17 21:25:38

une façon orthodoxe d'y parvenir, c'est en définissant une nouvelle fonction:

public static String join(String join, String... strings) {
    if (strings == null || strings.length == 0) {
        return "";
    } else if (strings.length == 1) {
        return strings[0];
    } else {
        StringBuilder sb = new StringBuilder();
        sb.append(strings[0]);
        for (int i = 1; i < strings.length; i++) {
            sb.append(join).append(strings[i]);
        }
        return sb.toString();
    }
}

échantillon:

String[] array = new String[] { "7, 7, 7", "Bill", "Bob", "Steve",
        "[Bill]", "1,2,3", "Apple ][","~,~" };

String joined;
joined = join(" and ","7, 7, 7", "Bill", "Bob", "Steve", "[Bill]", "1,2,3", "Apple ][","~,~");
joined = join(" and ", array); // same result

System.out.println(joined);

sortie:

7, 7, 7 et Bill et Bob et Steve et [projet de Loi] et 1,2,3 et Apple ][ et ~,~

15
répondu Daniel De León 2015-07-08 19:31:22

vous pouvez utiliser la bibliothèque apache commons qui a une classe StringUtils et une méthode join.

vérifier ce lien: https://commons.apache.org/proper/commons-lang/javadocs/api.2.0/org/apache/commons/lang/StringUtils.html

notez que le lien ci-dessus peut devenir obsolète au fil du temps, auquel cas vous pouvez simplement rechercher sur le web" apache communs StringUtils", ce qui devrait vous permettre de trouver la dernière référence.

(référencé à partir de ce fil) Java équivalents de C# String.Format () et String.Join ()

8
répondu dcp 2017-05-23 12:26:42

solution Java 8 avec java.util.StringJoiner

Java 8 a une classe StringJoiner . Mais vous avez encore besoin d'écrire un peu de boilerplate, parce que C'est Java.

StringJoiner sj = new StringJoiner(" and ", "" , "");
String[] names = {"Bill", "Bob", "Steve"};
for (String name : names) {
   sj.add(name);
}
System.out.println(sj);
8
répondu klingt.net 2016-05-24 21:12:15

Vous pouvez faire ceci:

String aToString = java.util.Arrays.toString(anArray);
// Do not need to do this if you are OK with '[' and ']'
aToString = aToString.substring(1, aToString.length() - 1);

Ou un one-liner (seulement si vous ne voulez pas '[' et ']')

String aToString = java.util.Arrays.toString(anArray).substring(1).replaceAll("\]$", "");

Espérons que cette aide.

6
répondu NawaMan 2009-11-17 21:18:44

une façon amusante de le faire avec pur JDK, en une seule ligne de service:

String[] array = new String[] { "Bill", "Bob", "Steve","[Bill]","1,2,3","Apple ][" };
String join = " and ";

String joined = Arrays.toString(array).replaceAll(", ", join)
        .replaceAll("(^\[)|(\]$)", "");

System.out.println(joined);

sortie:

Bill et Bob et Steve et [projet de Loi] et 1,2,3 et Apple ][


Un pas de trop parfaite et de ne pas trop s'amusant!

String[] array = new String[] { "7, 7, 7","Bill", "Bob", "Steve", "[Bill]",
        "1,2,3", "Apple ][" };
String join = " and ";

for (int i = 0; i < array.length; i++) array[i] = array[i].replaceAll(", ", "~,~");
String joined = Arrays.toString(array).replaceAll(", ", join)
        .replaceAll("(^\[)|(\]$)", "").replaceAll("~,~", ", ");

System.out.println(joined);

sortie:

7, 7, 7 et Bill et Bob et Steve et [projet de Loi] et 1,2,3 et Apple ][

4
répondu Daniel De León 2013-07-22 19:11:07

vous pouvez essayer la méthode Apache Commons StringUtils join:

http://commons.apache.org/lang/api/org/apache/commons/lang/StringUtils.html#join (java.util.Iterator , java.lang.String)

j'ai trouvé que Apache StringUtils ramasse du jdk de mou ;-)

3
répondu Upgradingdave 2009-11-17 21:19:32

si vous utilisez Eclipse Collections (anciennement GS Collections ), vous pouvez utiliser la méthode makeString() .

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

String string = ListAdapter.adapt(list).makeString(" and ");

Assert.assertEquals("Bill and Bob and Steve", string);

si vous pouvez convertir votre List en un type de Collections Eclipse, alors vous pouvez vous débarrasser de l'adaptateur.

MutableList<String> list = Lists.mutable.with("Bill", "Bob", "Steve");
String string = list.makeString(" and ");

si vous voulez juste une chaîne séparée par une virgule, Vous pouvez utiliser la version de makeString() qui ne prend aucun paramètre.

Assert.assertEquals(
    "Bill, Bob, Steve", 
    Lists.mutable.with("Bill", "Bob", "Steve").makeString());

Note: je suis un committer pour les Collections Eclipse.

3
répondu Craig P. Motlin 2017-01-19 07:24:37

API de goyave de Google a également .join (), bien que (comme cela devrait être évident avec les autres réponses), Apache Commons soit à peu près la norme ici.

2
répondu Dean J 2009-11-17 21:21:30

MODIFIER

j'ai aussi remarqué le problème de mise en œuvre sous-jacent toString() , et l'élément contenant le séparateur, mais je pensais que j'étais paranoïaque.

comme j'ai deux commentaires à ce sujet, je change ma réponse en:

    static String join( List<String> list , String replacement  ) {
        StringBuilder b = new StringBuilder();
        for( String item: list ) { 
            b.append( replacement ).append( item );
        }
        return b.toString().substring( replacement.length() );
    }

qui ressemble assez similaire à la question originale.

donc si vous n'avez pas envie d'ajouter le pot entier à votre projet, vous pouvez utiliser ce.

je pense qu'il n'y a rien de mal avec votre code d'origine. En fait, l'alternative que tout le monde suggère semble presque la même ( bien qu'elle fasse un certain nombre de validations supplémentaires)

la voici, ainsi que la licence Apache 2.0.

public static String join(Iterator iterator, String separator) {
       // handle null, zero and one elements before building a buffer
       if (iterator == null) {
           return null;
       }
       if (!iterator.hasNext()) {
           return EMPTY;
       }
       Object first = iterator.next();
       if (!iterator.hasNext()) {
           return ObjectUtils.toString(first);
       }

       // two or more elements
       StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small
       if (first != null) {
           buf.append(first);
       }

       while (iterator.hasNext()) {
           if (separator != null) {
               buf.append(separator);
           }
           Object obj = iterator.next();
           if (obj != null) {
               buf.append(obj);
           }
       }
       return buf.toString();
   }

Maintenant, nous savons, je vous remercie open source

2
répondu OscarRyz 2009-11-17 22:27:07

avec java 1.8 stream peut être utilisé,

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
List<String> list = Arrays.asList("Bill","Bob","Steve").
String str = list.stream().collect(Collectors.joining(" and "));
2
répondu Saurabh 2018-06-09 06:53:42

Java 8 apporte de la

Collectors.joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

méthode, qui est nullsafe en utilisant prefix + suffix pour les valeurs nulles.

Il peut être utilisé de la manière suivante:

String s = stringList.stream().collect(Collectors.joining(" and ", "prefix_", "_suffix"))

la méthode Collectors.joining(CharSequence delimiter) appelle simplement joining(delimiter, "", "") en interne.

1
répondu thg 2018-03-12 14:45:52

vous pouvez l'utiliser à partir de Spring Framework StringUtils. Je sais qu'il a déjà été mentionné, mais vous pouvez réellement prendre juste ce code et il fonctionne immédiatement, sans avoir besoin de Printemps.

// from https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/util/StringUtils.java

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class StringUtils {
    public static String collectionToDelimitedString(Collection<?> coll, String delim, String prefix, String suffix) {
        if(coll == null || coll.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        Iterator<?> it = coll.iterator();
        while (it.hasNext()) {
            sb.append(prefix).append(it.next()).append(suffix);
            if (it.hasNext()) {
                sb.append(delim);
            }
        }
        return sb.toString();
    }
}
0
répondu EpicPandaForce 2017-01-16 00:33:10

essayez ceci:

java.util.Arrays.toString(anArray).replaceAll(", ", ",")
                .replaceFirst("^\[","").replaceFirst("\]$","");
-3
répondu jorge 2013-09-02 21:19:40