5

実際の Java 8 の作成者は、次のクラスを記述します。

class ToListCollector<T> implements Collector<T, List<T>, List<T>> {

    @Override
    public Supplier<List<T>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<T>, T> accumulator() {
        return List::add;
    }

    @Override
    public BinaryOperator<List<T>> combiner() {
        return (l1, l2) -> {
            l1.addAll(l2);
            return l1;
        };
    }

    @Override
    public Function<List<T>, List<T>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
    }
}

それから彼は Characteristic enum の異なる値が何を意味するかについて話します。そして、彼が書いたこのコレクターが IDENTITY_FINISH および CONCURRENT であり、UNORDERED ではない理由を次のように説明しています。

これまでに開発された ToListCollector は IDENTITY_FINISH です。これは、ストリーム内の要素を蓄積するために使用されるリストが既に期待される最終結果であり、それ以上の変換を必要としないためです。この順序を結果のリストに保持したい。最後に、これは CONCURRENT ですが、先ほど述べたように、ストリームは、基になるデータ ソースが順序付けされていない場合にのみ並列で処理されます。

基になるソースが順序付けされていない場合にのみストリームが並列処理されるのはなぜですか? まだ並行して処理されると思いますが、combiner() は順序を維持する必要があります。本の間違いですか?

Brian Goetz は、この投稿の最後のパラグラフで、順序付けられたストリームの並列処理について非常に明確に述べていると思います。

本のページ数は 192 ~ 193 です。

4

1 に答える 1