374 Stimmen

Wie kann man in Java am besten eine Zeichenkette mit abgegrenzten Elementen erstellen?

Bei der Arbeit in einer Java-Anwendung musste ich kürzlich eine durch Kommata getrennte Liste von Werten zusammenstellen, die ich an einen anderen Webdienst weitergeben wollte, ohne im Voraus zu wissen, wie viele Elemente es sein würden. Das Beste, was mir auf Anhieb einfiel, war so etwas wie dieses:

public String appendWithDelimiter( String original, String addition, String delimiter ) {
    if ( original.equals( "" ) ) {
        return addition;
    } else {
        return original + delimiter + addition;
    }
}

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

Mir ist klar, dass dies nicht besonders effizient ist, da überall Zeichenketten erstellt werden, aber mir ging es mehr um Klarheit als um Optimierung.

In Ruby kann ich stattdessen etwas Ähnliches machen, was sich viel eleganter anfühlt:

parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");

Aber da Java keinen Join-Befehl hat, konnte ich nichts Vergleichbares finden.

Wie lässt sich dies in Java am besten bewerkstelligen?

28voto

gladiator Punkte 714

In Java 8 können Sie dies wie folgt tun:

list.stream().map(Object::toString)
        .collect(Collectors.joining(delimiter));

wenn die Liste Nullen enthält, können Sie verwenden:

list.stream().map(String::valueOf)
        .collect(Collectors.joining(delimiter))

es unterstützt auch Präfix und Suffix:

list.stream().map(String::valueOf)
        .collect(Collectors.joining(delimiter, prefix, suffix));

20voto

Vinko Vrsalovic Punkte 252104

Man kann es verallgemeinern, aber es gibt kein Join in Java, wie Sie richtig sagen.

Diese könnte besser funktionieren.

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}

15voto

Stu Thompson Punkte 37628

Verwenden Sie einen Ansatz, der auf java.lang.StringBuilder ! ("Eine veränderbare Folge von Zeichen.")

Wie Sie bereits erwähnt haben, werden durch all diese String-Verkettungen überall Strings erzeugt. StringBuilder wird das nicht tun.

Warum StringBuilder anstelle von StringBuffer ? Von der StringBuilder javadoc:

Wenn möglich, wird empfohlen, diese Klasse anstelle von StringBuffer zu verwenden, da sie bei den meisten Implementierungen schneller sein wird.

10voto

Eric Normand Punkte 3616

Ich würde Google Collections verwenden. Es gibt eine nette Join-Funktion.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html

Aber wenn ich es selbst schreiben wollte,

package util;

import java.util.ArrayList;
import java.util.Iterable;
import java.util.Collections;
import java.util.Iterator;

public class Utils {
    // accept a collection of objects, since all objects have toString()
    public static String join(String delimiter, Iterable<? extends Object> objs) {
        if (objs.isEmpty()) {
            return "";
        }
        Iterator<? extends Object> iter = objs.iterator();
        StringBuilder buffer = new StringBuilder();
        buffer.append(iter.next());
        while (iter.hasNext()) {
            buffer.append(delimiter).append(iter.next());
        }
        return buffer.toString();
    }

    // for convenience
    public static String join(String delimiter, Object... objs) {
        ArrayList<Object> list = new ArrayList<Object>();
        Collections.addAll(list, objs);
        return join(delimiter, list);
    }
}

Ich denke, dass es mit einer Objektsammlung besser funktioniert, da man die Objekte nicht mehr in Strings umwandeln muss, bevor man sie zusammenfügt.

8voto

Apache Commons Die Klasse StringUtils hat eine Join-Methode.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X