私はいくつかを持っています Set<String>
sおよびこれらをそれぞれ単一のString
に変換します。元のSet
の各要素は空白「」で区切られます。素朴な最初のアプローチは、このようにしています
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();
誰もがこれを行うためのより速く、きれいな、またはより効率的な方法を考えることができますか?
Commons/langでは、 StringUtils.join を使用してこれを行うことができます。
_String str_1 = StringUtils.join(set_1, " ");
_
簡潔にするために、本当にそれを打ち負かすことはできません。
更新:
この答えを読み直して、私は グアバのジョイナーに関する他の答え を好むでしょう。実際、最近では、Apacheコモンズの近くには行きません。
別の更新:
Java 8はメソッド String.join()
を導入しました
_String joined = String.join(",", set);
_
これはGuavaバージョンほど柔軟ではありませんが、クラスパスにGuavaライブラリがない場合に便利です。
Java 8を使用している場合は、 native
String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
方法:
指定された区切り文字のコピーで結合された
String
要素のコピーで構成される新しいCharSequence
を返します。例えば: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
はIterable
を実装するため、単純に以下を使用します。
String.join(" ", set_1);
Seanizerのcommons-langの答えの対比として、Googleの Guava Libraries (これはcommons-langの「後継者」と考えられます)を使用している場合は、 Joiner :
Joiner.on(" ").join(set_1);
次のようなことを行うためのいくつかのヘルパーメソッドの利点:
Joiner.on(" ").skipNulls().join(set_1);
// If 2nd item was null, would produce "1, 3"
または
Joiner.on(" ").useForNull("<unknown>").join(set_1);
// If 2nd item was null, would produce "1, <unknown>, 3"
また、StringBuildersおよびWritersへの直接追加、およびその他のそのような機能もサポートしています。
StringUtilライブラリを使用できないので(これ以上の選択肢はありません)、標準Javaを使用してこれを思いつきました。.
セットデータにカンマや角かっこが含まれていないことに確信がある場合は、次のように使用できます。
mySet.toString().replaceAll("\\[|\\]","").replaceAll(","," ");
「a」、「b」、「c」のセットは、.toString()を介して文字列「[a、b、c]」に変換されます。
次に、必要に応じて余分な句読点を置き換えます。
汚い。
たぶんより短い解決策:
public String test78 (Set<String> set) {
return set
.stream()
.collect(Collectors.joining(" "));
}
または
public String test77 (Set<String> set) {
return set
.stream()
.reduce("", (a,b)->(a + " " + b));
}
しかし、ネイティブ、間違いなく高速
public String test76 (Set<String> set) {
return String.join(" ", set);
}
私はこの方法を使用します:
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;
}
私はコードの複製について混乱しています。なぜそれを1つのセットを取り、1つの文字列を返す関数に含めるのでしょうか。
それ以外に、期待される容量についてのヒントを文字列ビルダーに与えることを除いて、あなたができることがたくさんあるかどうかはわかりません(設定サイズと文字列の長さの合理的な期待に基づいて計算できる場合)。
このためのライブラリ関数もありますが、それらが大幅に効率的であるとは思いません。
これは、セットからストリームを作成し、次に示すように、reduce操作を使用して要素を結合することで実行できます(Java 8ストリームチェック here の詳細について):
Optional<String> joinedString = set1.stream().reduce(new
BinaryOperator<String>() {
@Override
public String apply(String t, String u) {
return t + " " + u;
}
});
return joinedString.orElse("");