Java: Konvertiere die Liste <String> in einen String



Answers

Alle Verweise auf Apache Commons sind in Ordnung (und das ist, was die meisten Leute verwenden), aber ich denke, dass die Guava Entsprechung, Joiner , eine viel schönere API hat.

Sie können den einfachen Join-Fall mit machen

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

aber auch leicht mit Nullen umgehen:

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

oder

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

und (nützlich genug, wenn es darum geht, es Commons-lang vorzuziehen), die Fähigkeit, mit Maps umzugehen:

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

das ist sehr nützlich für das Debuggen usw.

Question

JavaScript hat Array.join()

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

Hat Java so etwas? Ich weiß, dass ich selbst mit StringBuilder etwas zusammenbasteln kann:

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();
}

... aber es macht keinen Sinn, das zu tun, wenn etwas wie dieses bereits Teil des JDK ist.




Wenn Sie Eclipse Collections (ehemals GS Collections ) verwenden, können Sie die Methode makeString() verwenden.

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

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

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

Wenn Sie Ihre List in einen Eclipse Collections-Typ konvertieren können, können Sie den Adapter loswerden.

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

Wenn Sie nur eine durch Kommas getrennte Zeichenfolge wünschen, können Sie die Version von makeString() , die keine Parameter makeString() .

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

Hinweis: Ich bin ein Committer für Eclipse Collections.




Unter Android können Sie die TextUtils- Klasse verwenden.

TextUtils.join(" and ", names);



Ein orthodoxer Weg, um es zu erreichen, besteht darin, eine neue Funktion zu definieren:

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();
    }
}

Probe:

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);

Ausgabe:

7, 7, 7 und Bill und Bob und Steve und [Bill] und 1,2,3 und Apple] [und ~, ~




Eine unterhaltsame Art, es mit reinem JDK zu machen, in einer Dienstlinie:

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);

Ausgabe:

Bill und Bob und Steve und [Bill] und 1,2,3 und Apple] [

Ein nicht zu perfekter und nicht zu lustiger Art und Weise!

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);

Ausgabe:

7, 7, 7 und Bill und Bob und Steve und [Bill] und 1,2,3 und Apple] [




Java 8 Lösung mit java.util.StringJoiner

Java 8 hat eine StringJoiner Klasse. Aber Sie müssen immer noch ein bisschen Text schreiben, weil es Java ist.

StringJoiner sj = new StringJoiner(" and ", "" , "");
String[] names = {"Bill", "Bob", "Steve"};
for (String name : names) {
   sj.add(name);
}
System.out.println(sj);



BEARBEITEN

Ich toString() auch das zugrunde liegende Implementierungsproblem toString() und das Element, das das Trennzeichen enthält, aber ich dachte, ich wäre paranoid.

Da ich zu diesem Thema zwei Kommentare habe, ändere ich meine Antwort wie folgt:

    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() );
    }

Das sieht der Originalfrage ziemlich ähnlich.

Wenn Sie also nicht das ganze Glas zu Ihrem Projekt hinzufügen möchten, können Sie dies verwenden.

Ich denke, es ist nichts falsch mit Ihrem ursprünglichen Code. Tatsächlich sieht die von allen vorgeschlagene Alternative fast gleich aus (obwohl sie eine Reihe zusätzlicher Validierungen durchführt).

Hier ist es, zusammen mit der Apache 2.0-Lizenz.

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();
   }

Jetzt wissen wir, danke Open Source




Sie können dies aus den StringUtils von Spring Framework verwenden. Ich weiß, dass es bereits erwähnt wurde, aber Sie können diesen Code tatsächlich nehmen und es funktioniert sofort, ohne Frühling dafür zu benötigen.

// 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();
    }
}



Ich habe dieses geschrieben (ich benutze es für Beans und nutze toString , also schreibe 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();
}

Aber die Collection wird von JSP nicht unterstützt, also schrieb ich für TLD:

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();
}

und in die .tld Datei .tld :

<?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>

und verwende es in JSP-Dateien als:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}



Drei Möglichkeiten in 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("");





Links



Tags

java java   list