【JavaGold勉強記#3】Collecterインタフェース編

javaGold資格取得に向けた勉強記第3回は「Collecterインタフェース」についてです。

Collecterインタフェースとは?

ストリームのリダクション操作のためのインタフェースで、処理途中のオブジェクトを適切に扱うことができます。

リダクション操作とは、一連の入力要素を受け取り、結合操作を繰り返し適用することで、単一のサマリー結果を出力する操作のことです。

クラスの定義

java.util.stream.Collecter<T, A, R>インタフェースは、3つの型パラメータを受け取ります。

1つ目はストリーム内の要素の型
2つ目は処理途中の値を保持するためのオブジェクト
3つ目は最終的な結果の型です。

public class javaGold implements Collector<String, StringBuilder, String> {
}

実現すべき5つの抽象メソッド

Collecterには5つの抽象メソッドがあり、これらすべてを継承したクラスで実装しなければなりません。
抽象メソッドとは、本体がなく、シグニチャ(メソッド名や引数、戻り値)だけで構成されるメソッドで、abstract修飾子を付与して定義します。
その性質上、そのままでは利用できないため、サブクラスでオーバーライドしなければなりません。

supplierメソッド

supplierメソッドは、処理途中の値を保持するためのオブジェクトを生成するメソッドです。
このメソッドは、引数は受け取らず、戻り値はSupplier型のラムダ式でなければなりません。

次のコードでは、ラムダ式の代わりにメソッド参照を使って、StringBuilderのインスタンスを生成して戻すSupplier型の式です。

@Override
public Supplier<StringBuilder> supplier(){
     return StringBuilder::new;
}

accumulatorメソッド

accumulatorメソッドは、具体的に実行したい処理を記述したBiConsumer型のラムダ式を戻すメソッドです。

次のコードでは、builderとstrという変数でStringBuilder型とString型の引数をそれぞれ受け取っています。

@Override
public BiConsumer<StringBuilder, String> accumulator(){
    return (builder, str) -> {
        if(builder.length() != 0){
            builder.append(",");
        }
        builder.append(str);
    };
}

combinerメソッド

combinerメソッドは、並列処理をしているときに個々に作られた処理途中の値を保持するためのオブジェクトを結合するメソッドです。
combinerメソッドの戻り値型は、結合対象であるオブジェクト2つを引数として受け取るBinaryOperator型です。

次のコードでは、2つのStringBuilderを受け取り、結合する処理を実装しています。

@Override
public BinaryOperator<StringBuilder> combiner() {
    return (a, b) -> {
        a.append(b);
        return a;
    };
}

finisherメソッド

finisherメソッドは、処理結果を戻すラムダ式を提供するメソッドです。

次のコードでは、StringBuilder型を引数に受け取り、String型の戻り値を戻すFunction型のラムダ式を戻します

@Override
public Function<StringBuilder, String> finisher(){
    return builder -> builder.toString();
}

characteristicsメソッド

characteristicsメソッドは、Collectorの特徴を表すEnumのセットを戻すメソッドです。

Collecterの特徴には次のような種類があります。
Collecterクラスの内部EnumとしてCollecter.Characteristicsが用意されています。

列挙子概要
CONCURRENTこのCollecterが並行処理をすることを表す
IDENTITY_FINISHこのCollecterのfinisherメソッドが省略可能であることを表す
UNORDEREDコレクションの操作において順序の維持を保証しないことを表す

もし、これらを指定する必要がなければ、
java.util.EnumSetクラスnoneOfメソッドにCollecter.Characteristicsクラスのクラスリテラルを渡せば、Collecter.Characteristics型を扱う空のSetオブジェクトが生成されます。

@Override
public Set<Characteristics> characteristics(){
    return EnumSet.noneOf(Characteristics.class);
}

最後に

今回はCollecterインタフェースの基本についてまとめてみました。

次回はCollecterクラスについてまとめてみようと思いますので合わせてご覧になってください!