tocollection - mapping java stream




このようにJava 8 'Collector'クラスが設計されているのはなぜですか? (2)

2関連する理由

  • コンビネータを介した機能的構成 。 (あなたはまだオブジェクト指向の構成を行うことができますが、以下の点を見てください)
  • 代入対象が関数インタフェースである場合にラムダ式またはメソッド参照を介して簡潔な表現コードでビジネスロジックをフレーミングする可能性

    機能性組成物

    Collectors APIは、コンビネータを介して機能構成のための道を開く。小さい/最小の再利用可能な機能を構築し、これらのいくつかを興味深い方法でしばしば高度な機能/機能に組み合わせる。

    簡潔な表現コード

    以下では、関数ポインタ(Employee :: getSalary)を使用して、mapperの機能をEmployeeオブジェクトからintに設定しています。 summingIntはintを追加するロジックを満たし、したがって一緒に結合されて、宣言型コードの1行に書き出された給与の合計を得ます。

    //従業員の給与の合計を計算するint total = employees.stream().collect(Collectors.summingInt( Employee :: getSalary )));

Java 8は新しいStream APIを導入し、 java.util.stream.Collectorはデータストリームを集約/収集する方法を定義するインタフェースです。

ただし、Collectorインターフェイスは次のように設計されています。

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

なぜそれは次のように設計されていないのですか?

public interface Collector<T, A, R> {
    A supply();
    void accumulate(A accumulator, T value);
    A combine(A left, A right);
    R finish(A accumulator);
}

後者の方が実装がはるかに簡単です。 前者のように考えるにはどうしたのですか?


構成は継承より優先されます。

あなたの質問の最初のパターンは、モジュール構成の一種です。 コレクタインタフェースの実装は、サプライヤ、アキュムレータなどの様々な実装を提供することができます。これは、サプライヤ、アキュムレータなどの実装の既存のプールからコレクタ実装を構成できることを意味します。 これは再利用にも役立ち、2つのコレクターが同じAccumulatorの実装を使用する可能性があります。 Stream.collect()は、指定された動作を使用します。

第2のパターンでは、コレクタの実装はすべての機能を単独で実装する必要があります。 あらゆる種類のバリエーションでは、親実装をオーバーライドする必要があります。 2つのコレクターがステップのための類似したロジック、例えば蓄積を持っている場合は、再利用の余地が少なく、コードの重複もあります。





collectors