wake-up-neo.com

Der schnellste Weg, um den Inhalt von Set <String> in einen einzelnen String mit durch ein Leerzeichen getrennten Wörtern zu setzen?

Ich habe ein paar Set<String>s und möchten jedes dieser Elemente in ein einzelnes String umwandeln, wobei jedes Element des ursprünglichen Set durch ein Leerzeichen "" getrennt ist. Ein naiver erster Ansatz macht es so

Set<String> set_1;
Set<String> set_2;

StringBuilder builder = new StringBuilder();
for (String str : set_1) {
  builder.append(str).append(" ");
}

this.string_1 = builder.toString();

builder = new StringBuilder();
for (String str : set_2) {
  builder.append(str).append(" ");
}

this.string_2 = builder.toString();

Kann sich jemand eine schnellere, schönere oder effizientere Möglichkeit vorstellen, dies zu tun?

49
Lars Andren

Mit commons/lang können Sie dies mit StringUtils.join tun:

String str_1 = StringUtils.join(set_1, " ");

Das ist der Kürze halber nicht zu übertreffen.

Update:

Wenn ich diese Antwort noch einmal lese, würde ich die andere Antwort in Bezug auf Guavas Schreiner jetzt vorziehen. Tatsächlich gehe ich heutzutage nicht in die Nähe von Apache Commons.

Ein weiteres Update:

Java 8 führte die Methode String.join() ein

String joined = String.join(",", set);

Dies ist zwar nicht so flexibel wie die Guava-Version, aber praktisch, wenn Sie die Guava-Bibliothek nicht in Ihrem Klassenpfad haben.

96

Wenn Sie Java 8 verwenden, können Sie native verwenden

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

methode:

Gibt ein neues String zurück, das aus Kopien der CharSequence -Elemente besteht, die zusammen mit einer Kopie des angegebenen Begrenzers verbunden sind. Beispielsweise:

 Set<String> strings = new LinkedHashSet<>();
 strings.add("Java"); strings.add("is");
 strings.add("very"); strings.add("cool");
 String message = String.join("-", strings);
 //message returned is: "Java-is-very-cool"

Set implementiert Iterable, verwenden Sie also einfach:

String.join(" ", set_1);
29
Jasper de Vries

Als Kontrapunkt zu Seanizers Commons-Lang-Antwort würden Sie - verwenden, wenn Sie Googles Guava Libraries (was ich in vielerlei Hinsicht als den "Nachfolger" von Commons-Lang bezeichnen würde). Schreiner :

Joiner.on(" ").join(set_1);

mit dem Vorteil einiger Hilfsmethoden, Dinge zu tun wie:

Joiner.on(" ").skipNulls().join(set_1);
// If 2nd item was null, would produce "1, 3"

oder

Joiner.on(" ").useForNull("<unknown>").join(set_1);
// If 2nd item was null, would produce "1, <unknown>, 3"

Es bietet auch Unterstützung für das direkte Anhängen an StringBuilder und Writers sowie für andere derartige Feinheiten.

20
Cowan

Ich habe die StringUtil-Bibliothek nicht zur Verfügung (ich habe keine andere Wahl), also benutze ich Standard Java).

Wenn Sie sicher sind, dass Ihre Daten keine Kommas oder eckigen Klammern enthalten, können Sie Folgendes verwenden:

mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," ");

Eine Menge von "a", "b", "c" wird über .toString () in die Zeichenfolge "[a, b, c]" konvertiert.

Ersetzen Sie dann die zusätzliche Interpunktion, falls erforderlich.

Schmutz.

6
user2808054

Vielleicht eine kürzere Lösung:

public String test78 (Set<String> set) {
    return set
        .stream()
        .collect(Collectors.joining(" "));
}

oder

public String test77 (Set<String> set) {
    return set
        .stream()
        .reduce("", (a,b)->(a + " " + b));
}

aber einheimisch, definitiv schneller

public String test76 (Set<String> set) {
    return String.join(" ", set);
}
4

Ich benutze diese Methode:

public static String join(Set<String> set, String sep) {
    String result = null;
    if(set != null) {
        StringBuilder sb = new StringBuilder();
        Iterator<String> it = set.iterator();
        if(it.hasNext()) {
            sb.append(it.next());
        }
        while(it.hasNext()) {
            sb.append(sep).append(it.next());
        }
        result = sb.toString();
    }
    return result;
}
4
tuxdna

Ich bin verwirrt über die Codereplikation. Warum nicht in eine Funktion zerlegen, die eine Menge nimmt und eine Zeichenfolge zurückgibt?

Abgesehen davon bin ich mir nicht sicher, ob Sie viel tun können, außer dem Stringbuilder einen Hinweis auf die erwartete Kapazität zu geben (wenn Sie diese anhand der festgelegten Größe und der vernünftigen Erwartung der Stringlänge berechnen können).

Es gibt auch Bibliotheksfunktionen, aber ich bezweifle, dass sie wesentlich effizienter sind.

2
Uri

Dies kann durch Erstellen eines Streams aus der Menge und anschließendes Kombinieren der Elemente mit einer Reduktionsoperation wie unten gezeigt erreicht werden (für weitere Details zu Java 8 Streams überprüfen hier ):

Optional<String> joinedString = set1.stream().reduce(new 
BinaryOperator<String>() {

     @Override
     public String apply(String t, String u) {

       return t + " " + u;
    }
});
return joinedString.orElse("");
2
Ehab Qadah