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. groupingBy と partitioningBy の違い
- 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を問う問題」にも、この記事を何度も読み返せば自信を持って臨めます!