現在、複数の項目がある場合のみ)Collectors.joining(に接頭辞と接尾辞を追加します。

ジョン・ドウ:

私は、文字列のストリームを持っています:

Stream<String> stream = ...;

私はこれらのアイテムを連結した文字列構築したい,セパレータとしては。私は、次のようにこれを実行します。

stream.collect(Collectors.joining(","));

今、私は接頭辞を追加したい[と接尾辞を]複数の項目があった場合にのみ、この出力に。例えば:

  • a
  • [a,b]
  • [a,b,c]

これは、最初のマテリアライズせずに行うことができますStream<String>List<String>、その後にチェックList.size() == 1コードでは:

public String format(Stream<String> stream) {
    List<String> list = stream.collect(Collectors.toList());

    if (list.size() == 1) {
        return list.get(0);
    }
    return "[" + list.stream().collect(Collectors.joining(",")) + "]";
}

これは、最初に適用することができるようにストリームに再度リストにストリームを変換してする奇妙な感じCollectors.joining(",")私は(中に行われ、全体の流れをループすることの次善のだと思うCollectors.toList())は、1つ以上の項目を(s)が存在する場合にのみ発見するが。

私は自分自身を実装することができCollector<String, String>、その後カウント与えられた項目や使用回数をカウントします。directerの方法がある場合しかし、私は疑問に思って。

ストリームが空の場合、この質問は、意図的にそこにケースを無視します。

シンタグマ:

はい、これはカスタム使用可能であるCollectorストリーム内の項目の数やオーバーロードして匿名オブジェクトを使用するインスタンスtoString()メソッドを:

public String format(Stream<String> stream) {
    return stream.collect(
            () -> new Object() {
                StringJoiner stringJoiner = new StringJoiner(",");
                int count;

                @Override
                public String toString() {
                    return count == 1 ? stringJoiner.toString() : "[" + stringJoiner + "]";
                }
            },
            (container, currentString) -> {
                container.stringJoiner.add(currentString);
                container.count++;
            },
            (accumulatingContainer, currentContainer) -> {
                accumulatingContainer.stringJoiner.merge(currentContainer.stringJoiner);
                accumulatingContainer.count += currentContainer.count;
            }
                         ).toString();
}

説明

Collector インタフェースは次のメソッドがあります。

public interface Collector<T,A,R> {
    Supplier<A> supplier();
    BiConsumer<A,T> accumulator();
    BinaryOperator<A> combiner();
    Function<A,R> finisher();
    Set<Characteristics> characteristics();
}

それは、この例には関係ありません、私は最後の方法を省略します。

ありcollect()、次のシグネチャを持つメソッドは:

<R> R collect(Supplier<R> supplier,
              BiConsumer<R, ? super T> accumulator,
              BiConsumer<R, R> combiner);

そして私たちの場合、それはに解決します:

<Object> Object collect(Supplier<Object> supplier,
              BiConsumer<Object, ? super String> accumulator,
              BiConsumer<Object, Object> combiner);
  • ではsupplier、私たちはのインスタンスを使用しているStringJoiner(基本的には同じものCollectors.joining()使っているが)。
  • ではaccumulator、私たちが使用しているStringJoiner::add()が、我々はうまくとしてカウントをインクリメント
  • ではcombiner、私たちが使用しているStringJoiner::merge()とアキュムレータに数を追加
  • 戻る前にformat()機能、我々は呼び出す必要がありtoString()、当社の蓄積ラップする方法をStringJoinerでインスタンスを[]単一要素ストリームの場合には、(またはされているとして、それを残します

空の場合の場合も、私はこのコレクタはより複雑にしないためにそれを残し、追加することができます。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=171242&siteId=1