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?
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.
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 derCharSequence
-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);
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.
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.
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);
}
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;
}
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.
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("");