Java 8 で提供される StringJoiner、この記事ではこの文字列結合の新機能を紹介します。
文字列を連結する方法が何通りあるか知りたい場合は、簡単な方法をお教えします。Intellij IDEA で Java Bean を定義し、ショートカット キーを使用して toString メソッドを自動生成してみてください。IDEA は次のことを要求します。複数の toString を生成します。戦略が利用可能です。
![][2]
現在、私が使用している IDEA の toString 生成戦略は、デフォルトで JDK 1.8 が提供する StringJoiner を使用します。
導入
StringJoiner は、区切り文字 (オプション) で区切られた一連の文字を構築するために使用される java.util パッケージ内のクラスであり、指定されたプレフィックスで始まり、指定されたサフィックスで終わることができます。これは、StringBuilder クラスを使用して各文字列の後に区切り文字を追加することもできますが、StringJoiner を使用すると、多くのコードを記述せずにこれを簡単に行うことができます。
StringJoiner クラスには 2 つのコンストラクターと 5 つのパブリック メソッドがあります。最も一般的に使用されるメソッドは add メソッドと toString メソッドで、StringBuilder の append メソッドと toString メソッドに似ています。
使用法
StringJoiner の使用法は比較的簡単で、次のコードでは文字列の結合に StringJoiner を使用しています。
public class StringJoinerTest {
public static void main(String[] args) {
StringJoiner sj = new StringJoiner("Hollis");
sj.add("hollischuang");
sj.add("Java干货");
System.out.println(sj.toString());
StringJoiner sj1 = new StringJoiner(":","[","]");
sj1.add("Hollis").add("hollischuang").add("Java干货");
System.out.println(sj1.toString());
}
}
上記のコードの出力は次のとおりです。
hollischuangHollisJava干货
[Hollis:hollischuang:Java干货]
StringJoiner(CharSequence delimiter)
one を初期化するときStringJoiner
、これはdelimiter
実際には区切り文字であり、変数文字列の初期値ではないことに注意してください。
StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)
の 2 番目と 3 番目のパラメータは、それぞれ、連結された文字列のプレフィックスとサフィックスです。
原理
簡単な使用法を紹介した後、この StringJoiner の原理と実装方法を見てみましょう。主に add メソッドを見てください。
public StringJoiner add(CharSequence newElement) {
prepareBuilder().append(newElement);
return this;
}
private StringBuilder prepareBuilder() {
if (value != null) {
value.append(delimiter);
} else {
value = new StringBuilder().append(prefix);
}
return value;
}
見慣れた図を見ました - StringBuilder、そうです、StringJoiner は実際には StringBuilder に依存して実装されています。
StringJoiner が実際には StringBuilder によって実装されていることがわかった場合、そのパフォーマンスの低下は StringBuilder を直接使用した場合と同様であると推測できます。
StringJoiner が必要な理由
StringJoiner の使用法と原理を理解した後、多くの読者は疑問を持つかもしれません。明らかに StringBuilder はすでに存在するのに、なぜ Java 8 で StringJoiner を定義する必要があるのでしょうか。メリットは何ですか?
読者が Java 8 について十分な知識を持っている場合は、それが Stream に関連しているに違いないと推測できるかもしれません。
著者は、[Java ドキュメント][3] にも答えを見つけました。
StringJoiner は、Collectors.joining(CharSequence) を使用してストリームからフォーマットされた出力を作成するために使用できます。
Java で次のようなリストがあると想像してみてください。
List<String> list = ImmutableList.of("Hollis","hollischuang","Java干货");
それを次の形式の文字列に連結したい場合:
Hollis,hollischuang,Java干货
次の方法で実行できます。
StringBuilder builder = new StringBuilder();
if (!list.isEmpty()) {
builder.append(list.get(0));
for (int i = 1, n = list.size(); i < n; i++) {
builder.append(",").append(list.get(i));
}
}
builder.toString();
次のものも使用できます。
list.stream().reduce(new StringBuilder(), (sb, s) -> sb.append(s).append(','), StringBuilder::append).toString();
ただし、出力は若干異なり、二次処理が必要です。
Hollis,hollischuang,Java干货,
連結に「+」を使用することもできます。
list.stream().reduce((a,b)->a + "," + b).toString();
上記の方法では、コードが複雑であったり、性能が高くなかったり、直接的には望む結果が得られなかったりします。
このような要件を満たすには、Java 8 で提供されている StringJoiner が便利です。上記の要件に必要なコードは 1 行だけです。
list.stream().collect(Collectors.joining(":"))
それでおしまい。上記で使用した式の Collectors.joining のソース コードは次のとおりです。
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
実現原理は StringJoiner を使用することです。
もちろん、Collector
で直接使用してもStringBuilder
同様の機能が実現できるようですが、少々面倒です。したがって、Java 8 ではStringJoiner
豊富なStream
使用法が提供されます。
また、StringJoiner
プレフィックスやサフィックスの追加にも便利で、たとえば、取得したい文字列が乾物で[Hollis,hollischuang,Java干货]
はない場合Hollis,hollischuang,Java
、StringJoiner の利点はさらに明らかです。
要約する
この記事では、文字列の結合に使用できる、Java 8 で提供される変数文字列クラス StringJoiner を紹介します。
StringJoiner は実際には StringBuilder を通じて実装されるため、そのパフォーマンスは StringBuilder と同様であり、非スレッドセーフでもあります。
日々の開発で文字列のスプライシングが必要な場合、どのように選択すればよいでしょうか?
1. 単純な文字列連結の場合は、「+」を直接使用することを検討してください。
2. 文字列の連結が for ループ内で実行される場合は、StringBuilder
と の使用を検討してくださいStringBuffer
。
3.List
文字列が 1 つを介して接続されている場合は、それを使用することを検討してくださいStringJoiner
。