Java Gold SE11対策:Collectors完全理解!groupingByから自作Collectorまで試験頻出パターン総まとめ

アイキャッチ画像

Java Gold SE11の試験では、Stream の終端操作である collect() の理解が重要です。
特に Collectors クラスにあるメソッドの構文や使い方、そして Collector インタフェースの仕組みまで踏み込んだ問題が出題されます。

この記事では、よく使う既製のCollector群から、Collectorインタフェースの内部構造(自作)までを徹底解説します。

1. collect()とは? — 終端操作の中でも最重要

Stream の最終的な集約処理を担うのが collect() です。
基本的な構文は以下のとおり:

List<String> result = stream.collect(Collectors.toList());

この Collectors.toList() は、Collector インタフェースの実装クラスの1つを返しています。

2. よく使う Collectors のメソッド一覧

メソッド説明
toList() / toSet()要素をリストやセットに集約
joining()文字列の連結(引数で区切り指定も可能)
counting()要素数のカウント
mapping()中間で変換してから集約
groupingBy()指定した条件でグルーピング
partitioningBy()booleanで2分割
reducing()初期値と合成関数で1つにまとめる

3. groupingBypartitioningBy の違い

  • groupingBy は 任意の条件でグループを作る(Map<K, List<V>>)
  • partitioningBy は boolean値で2グループに分ける(Map<Boolean, List<V>>)

Map<String, List<Person>> byGender = 

    persons.stream().collect(Collectors.groupingBy(Person::getGender));

Map<Boolean, List<Integer>> evenOdd = 

    List.of(1, 2, 3, 4).stream().collect(Collectors.partitioningBy(i -> i % 2 == 0));

4. ネストした Collector の活用(マルチレベル)

複数階層のグルーピングにも対応可能:

Map<String, Map<String, List<Person>>> multiGrouped =

    persons.stream()

        .collect(Collectors.groupingBy(

            Person::getGender,

            Collectors.groupingBy(Person::getDepartment)

        ));

groupingBy の中に groupingBy を入れることで、多段階の分類も可能です。

5. Collectorインタフェースの仕組み(自作も出る!)

試験では Collector インタフェース自体の実装や5つの構成メソッドについて問われることがあります。
黒本でも頻出でした。

Collector<T, A, R> の型パラメータとは?

  • T:Streamの要素型
  • A:中間結果を保持するオブジェクト(例:ListやMap)
  • R:最終的な戻り値の型(Aと同じこともある)

▶ 5つのメソッドの役割と暗記法

質問該当メソッド役割
空の器は?supplier()新しい中間結果(A)を作る
1個ずつどう入れる?accumulator()T型の値をAに加える関数
並列処理後どう合体?combiner()並列実行の結果Aを結合
最後にどう変換?finisher()A → R に変換(場合によって不要)
特性は?characteristics()並列性や不変性の情報

▶ 自作の例(文字列を大文字にして結合)

Collector<String, StringBuilder, String> upperConcat = new Collector<>() {

    public Supplier<StringBuilder> supplier() {

        return StringBuilder::new;

    }

    public BiConsumer<StringBuilder, String> accumulator() {

        return (sb, s) -> sb.append(s.toUpperCase());

    }

    public BinaryOperator<StringBuilder> combiner() {

        return StringBuilder::append;

    }

    public Function<StringBuilder, String> finisher() {

        return StringBuilder::toString;

    }

    public Set<Characteristics> characteristics() {

        return Set.of(Characteristics.UNORDERED);

    }

};

このように、Collector のインスタンスを自作して collect() に渡すことも可能です。

6. Collector を渡す2つの方法

方法内容
パターン①Collectors.toList() など、既成のファクトリメソッドを使う
パターン②自作の Collector インスタンスを 直接渡す

試験では「collect() に渡しているのは何型か?」「内部で呼ばれるメソッドは?」という問いが出ることがあります。

まとめ:試験で意識すべきポイント

  • collect() の引数は Collector 型(toList()などはその実装を返している)
  • groupingBy, partitioningBy, joining などは使い方・構造に要注意
  • 自作の Collector では、5つのメソッドの意図を問う設問が出る
  • 特に supplier, accumulator, combiner, finisher, characteristics を用途で結びつけて覚える

おわりに

Collectors はJava Gold SE11試験でもかなり出題されやすいパートです。
単に「構文を覚える」だけでなく、「どう集約されるか」の仕組み(Collector の5メソッド)まで理解しておくことで、応用問題にも強くなります。

黒本に出ていたような「自作Collectorを問う問題」にも、この記事を何度も読み返せば自信を持って臨めます!