【Java学習|豆知識】JavaのStream APIでデータ集計を効率化!Collectors.groupingByの活用術

導入

業務アプリケーションの開発において、データベースから取得したリストを「カテゴリごと」や「IDごと」に分類したいという場面は非常に多いものです。かつてはforループとif文を駆使してMapを構築していましたが、Java 8以降のStream APIを利用すれば、わずか1行でこの処理を記述できます。本稿では、データ集計の定石であるCollectors.groupingByの使い方を解説します。

基礎知識

Collectors.groupingByは、Streamの要素を特定のキーに基づいてグループ化し、Map>の形式で出力するためのコレクターです。
Kはグルーピングの基準となるキー、Vは元の要素の型を表します。SQLで言うところの「GROUP BY句」に相当する処理をJavaのコード上で直感的に記述できるのが特徴です。

実装/解決策

グループ化を行うには、StreamのcollectメソッドにCollectors.groupingByを渡します。引数には「何をキーにするか」を指定するFunctionを渡すだけで、自動的に同じキーを持つ要素がリストとしてまとめられます。

サンプルプログラム

以下は、社員情報を部署ごとにグループ化する実用的なコード例です。

import java.util.;
import java.util.stream.Collectors;

public class GroupingExample {
// 社員クラス
record Employee(String name, String department) {}

public static void main(String[] args) {
List employees = Arrays.asList(
new Employee(“佐藤”, “開発部”),
new Employee(“鈴木”, “営業部”),
new Employee(“田中”, “開発部”),
new Employee(“高橋”, “人事部”)
);

// 部署名をキーにしてグループ化
Map> employeesByDept = employees.stream()
.collect(Collectors.groupingBy(Employee::department));

// 結果の出力
employeesByDept.forEach((dept, list) -> {
System.out.println(dept + “: ” + list);
});
}
}

応用・注意点

現場で活用する際のポイントをいくつか挙げます。

1. ダウンストリームコレクターの活用
単にリストにまとめるだけでなく、グループ化した後に「件数をカウントしたい」「特定のフィールドを取り出したい」といった場合は、第2引数に別のコレクターを渡すことができます。
例:Collectors.groupingBy(Employee::department, Collectors.counting()) とすれば、部署ごとの人数が取得できます。

2. Mapの型を制御する
デフォルトではHashMapが返されますが、順序を維持したい場合は、第3引数にSupplier(例:TreeMap::newやLinkedHashMap::new)を渡すことで、Mapの実装クラスを柔軟に変更可能です。

3. null値の扱い
キーとなるFunctionがnullを返す場合、groupingByは例外をスローします。データソースにnullが含まれる可能性がある場合は、事前にfilterで除外するか、Function内でnullチェックを行うようにしてください。

Stream APIを使いこなすことで、コードの可読性が劇的に向上します。ぜひ日々の開発に取り入れてみてください。

コメント

タイトルとURLをコピーしました