【Java学習|初心者向け】Java Stream APIを使いこなそう!Collectorsの便利機能を徹底解説

導入:なぜCollectorsを知る必要があるのか

JavaのStream APIを使っていると、「リスト内のデータを加工して、特定の形式でまとめたい」という場面によく出くわします。例えば、「名前をカンマ区切りで繋げたい」「年齢ごとにグループ分けしたい」といった処理です。これらをfor文やif文で書くとコードが長くなりがちですが、java.util.stream.Collectorsクラスを使えば、たった1行でスマートに解決できます。本記事では、現場で頻出する主要なCollectors関数を紹介します。

基礎知識:Collectorsとは何か

Collectorsは、Streamで処理した結果を「最終的にどんな形(List、Map、Stringなど)にまとめるか」を決定するツールボックスです。Streamの最後に.collect()メソッドを呼び出し、その引数としてCollectorsのメソッドを渡すことで、高度な集計操作が可能になります。

実装・解決策:主要なメソッドの使い方

それぞれのメソッドは以下のような目的で使い分けます。
1. joining(): 文字列を連結する
2. groupingBy(): 条件でリストをグループ化する
3. partitioningBy(): 条件で「真・偽」の2つに分ける
4. mapping(): 集計前に要素を変換する
5. filtering(): 集計前に条件で絞り込む
6. flatMapping(): 1対多の要素を平坦化してから集計する

サンプルプログラム:実用的なコード例

以下は、社員リストから様々な集計を行うサンプルです。

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

public class StreamExample {
public static void main(String[] args) {
List employees = Arrays.asList(
new Employee(“佐藤”, “開発部”, 25),
new Employee(“鈴木”, “営業部”, 30),
new Employee(“田中”, “開発部”, 35)
);

// 1. joining: 名前をカンマ区切りで結合
String names = employees.stream().map(Employee::getName).collect(Collectors.joining(“, “));
System.out.println(“名前一覧: ” + names);

// 2. groupingBy: 部署ごとにグループ化
Map> byDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment));

// 3. partitioningBy: 30歳以上かどうかで分ける
Map> partitioned = employees.stream().collect(Collectors.partitioningBy(e -> e.getAge() >= 30));

// 4. mapping & filtering: 開発部の人の名前だけ抽出
List devNames = employees.stream()
.collect(Collectors.filtering(e -> “開発部”.equals(e.getDepartment()),
Collectors.mapping(Employee::getName, Collectors.toList())));

System.out.println(“開発部メンバー: ” + devNames);
}
}

class Employee {
private String name;
private String department;
private int age;
public Employee(String n, String d, int a) { name = n; department = d; age = a; }
public String getName() { return name; }
public String getDepartment() { return department; }
public int getAge() { return age; }
}

応用・注意点:現場での落とし穴

Collectorsを組み合わせる際の注意点
Collectorsの強力な機能として「ダウンストリーム・コレクタ(集計の中に集計を入れる)」があります。例えばgroupingByの中でmappingを使い、部署ごとの「名前リスト」を作るといった手法です。

注意点:
1. メモリ消費量:大量のデータをgroupingByで分類すると、Mapオブジェクトがメモリを圧迫することがあります。データ量が膨大な場合は注意が必要です。
2. 可読性:あまりに複雑なネスト(groupingByの中にfilteringを入れて、さらにmappingして…)を作ると、コードが非常に読みづらくなります。複雑すぎる場合は、一度リストを生成してから処理を分けるなど、可読性とのバランスを意識してください。

これらを使いこなせれば、Javaのデータ処理能力が格段に向上します。ぜひ今のプロジェクトで試してみてください!

コメント

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