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.
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.
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.
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);
Sur Android , vous pourriez utiliser TextUtils de la classe.
TextUtils.join(" and ", names);
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.
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("");
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"));
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, ", ")}
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 ");
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 ~,~
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 ()
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);
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.
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 ][
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 ;-)
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.
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.
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
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 "));
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.
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();
}
}
essayez ceci:
java.util.Arrays.toString(anArray).replaceAll(", ", ",")
.replaceFirst("^\[","").replaceFirst("\]$","");