ここでは 「拡張 for 文」と 「Stream API」 で同じ処理を行った場合の流れを図解で比較します。
初心者でも「どっちが何をしているか」を直感的に理解できるようにしました。
例題:社員リストから部署ごとの人数を集計する
入力データ
class Employee {
String name;
String dept;
Employee(String n, String d){ name = n; dept = d; }
}
List<Employee> employees = List.of(
new Employee("Alice", "DeptA"),
new Employee("Bob", "DeptB"),
new Employee("Charlie", "DeptA"),
new Employee("David", "DeptB"),
new Employee("Eve", "DeptC")
);
Java1️⃣ 拡張 for 文で書く場合
コード
Map<String, Integer> deptCount = new HashMap<>();
for (Employee e : employees) {
deptCount.put(e.dept, deptCount.getOrDefault(e.dept, 0) + 1);
}
System.out.println(deptCount);
Java図解
[employeesリスト]
Alice-DeptA
Bob-DeptB
Charlie-DeptA
David-DeptB
Eve-DeptC
│
▼ (for ループで1件ずつ処理)
Alice → DeptA: カウント +=1 → deptCount={"DeptA":1}
Bob → DeptB: カウント +=1 → deptCount={"DeptA":1, "DeptB":1}
Charlie → DeptA: カウント +=1 → deptCount={"DeptA":2, "DeptB":1}
David → DeptB: カウント +=1 → deptCount={"DeptA":2, "DeptB":2}
Eve → DeptC: カウント +=1 → deptCount={"DeptA":2, "DeptB":2, "DeptC":1}
- 処理の流れ:1件ずつ「取り出して → 集計して → Mapに書き込む」
2️⃣ Stream API で書く場合
コード
Map<String, Long> deptCount = employees.stream()
.collect(Collectors.groupingBy(
e -> e.dept,
Collectors.counting()
));
System.out.println(deptCount);
Java図解
[employeesリスト]
Alice-DeptA
Bob-DeptB
Charlie-DeptA
David-DeptB
Eve-DeptC
│
▼ (stream生成)
groupingBy(dept) + counting()
│
▼ 集計処理はStream内部で自動
│
▼ 出力Map:
{"DeptA":2, "DeptB":2, "DeptC":1}
- 処理の流れ:
- stream() でリストを流し込み
- groupingBy + counting で自動集計
- Mapにまとめる
比較ポイント
| 観点 | 拡張 for 文 | Stream API |
|---|---|---|
| コード量 | やや長い | 短く、1ブロックで完結 |
| 処理の明確さ | 手続き的(どうやって集計するかを書く) | 宣言的(何をしたいかを書く) |
| 読みやすさ | 小規模で簡単 | 複雑な集計も1行で表現可 |
| 拡張性 | 集計方法を変えるとループ内処理を修正 | Collectors を変えるだけで簡単 |
| 並列化 | 自前で工夫が必要 | .parallelStream() で簡単 |
流れのイメージ(図)
[リスト]
Alice DeptA
Bob DeptB
Charlie DeptA
David DeptB
Eve DeptC
│
├─ 拡張 for 文: 1件ずつ Mapに書き込み
│
└─ Stream API : Stream -> groupingBy -> Map自動生成
- 拡張 for 文:ループ内で自分で集計ロジックを書く
- Stream API:内部で自動的に集計してくれるので1行で書ける
💡 実務での使い分け
- 小規模・単純処理 → 拡張 for 文が直感的
- 集計・変換・条件抽出 → Stream API が簡潔・可読性高い
- 並列化やパイプライン処理 → Stream API が有利


