Java Gold SE11対策:命令型と宣言型の違いから学ぶStreamの本質

Java Gold SE11の試験では、Stream APIがなぜ導入されたのかという思想的な背景も問われます。
その本質を理解する鍵が「命令型(imperative)と宣言型(declarative)」の違いにあります。
本記事では、従来のforループとの違いから始まり、Streamのパイプライン構造、中間操作・終端操作、そして遅延評価の概念まで、Streamの基礎を論理的に解説します。
目次
命令型と宣言型とは?
● 命令型(Imperative Programming)
「何をするか」よりも「どうやるか」に重点を置いた書き方。
List<String> list = List.of(“apple”, “banana”, “apricot”);
List<String> result = new ArrayList<>();
for (String s : list) {
if (s.startsWith(“a”)) {
result.add(s.toUpperCase());
}
}
- 要素を1つずつ取り出す
- 条件をifで書く
- 結果を明示的にaddする
→ 開発者が逐次処理の手続きをすべて記述しています。
● 宣言型(Declarative Programming)
「何をしたいか」に集中して、処理の流れは抽象化するスタイル。
List<String> result = list.stream()
.filter(s -> s.startsWith(“a”))
.map(String::toUpperCase)
.collect(Collectors.toList());
- 条件に合うものだけ選ぶ(filter)
- 変換処理を行う(map)
- 結果を収集する(collect)
→ 何をするかの宣言に徹していて、「どうやってループを回すか」は書いていません。
Streamのパイプライン構造
Stream APIの最大の特徴は、中間操作 → 終端操作というパイプライン構造です。
list.stream() // Streamの生成
.filter(…) // 中間操作
.map(…) // 中間操作
.collect(…) // 終端操作(ここで実行される!)
中間操作(Intermediate Operation)
- Streamを変換・フィルタするが、まだ実行されない
- 例:filter(), map(), sorted(), distinct()
終端操作(Terminal Operation)
- Streamの計算を実行するタイミング
- 例:collect(), forEach(), count()
forループとの違いを実感しよう
特徴 | forループ | Stream |
処理の記述方法 | 明示的(命令型) | 宣言的 |
並列処理 | 自力でスレッドを書く必要あり | parallelStream()で対応可 |
中間処理の再利用性 | 自分で変数・条件を書く必要あり | map/filterなどを組み合わせられる |
処理の実行タイミング | 逐次即時実行 | 遅延評価(後述) |
Streamは構文的に短くなることが目的ではなく、抽象度を上げて可読性・柔軟性・並列性を得ることが本質です。
遅延評価(Lazy Evaluation)
JavaのStreamは、中間操作だけでは実行されません。
Stream<String> s = list.stream()
.filter(x -> {
System.out.println(“filter: ” + x);
return x.startsWith(“a”);
});
// ここではまだ出力されない!
List<String> result = s.collect(Collectors.toList()); // ← ここで初めて実行
このように、終端操作が来るまで実行されない性質を**遅延評価(lazy evaluation)**と呼びます。
なぜ遅延評価?
- 不要な要素を早めに捨てられる
- 複数の中間操作を効率的に融合できる
- 並列処理やショートサーキットがしやすい
例:limit(5) などを前に持ってくると、処理数を削減できる!
実務にも効くStreamの利点
利点 | 内容 |
可読性の向上 | 処理の目的が1行ずつ明確に分かれる |
柔軟な組み合わせ | filter → map → collect の順序変更や再利用が簡単 |
並列処理対応 | parallelStream()で並列処理も簡単に |
不変性の促進 | 元のリストを変更しないスタイルになる |
まとめ:試験前に押さえておくべきポイント
試験論点 | チェック |
宣言型と命令型の違いを説明できるか? | ✅ |
forループとstreamの処理構造の違いを理解しているか? | ✅ |
中間操作と終端操作の区別がつくか? | ✅ |
遅延評価の概念を説明できるか? | ✅ |
実行タイミングはcollectなどの終端操作であると知っているか? | ✅ |
おわりに
Streamは単なるループの置き換えではありません。「何をしたいのか」を明確にしながら、柔軟な処理の組み立てができるのが最大の魅力です。
Java Gold SE11の試験では、「なぜforではなくstreamなのか」といった前提理解を問う設問もあります。ぜひこの宣言型思考をしっかりと押さえてください!