【Java中級者への道】もうforループは書かない!Stream APIでモダンなデータ処理 更新日: 2026年2月01日 私がJavaエンジニアとして働き始めた頃、コードレビューで先輩に最も多く指摘されたこと。それは「forループのネスト(入れ子)が深すぎて読めない」ということでした。 「リストから条件に合うものを探して、変換して、別のリストに入れる...」 たったそれだけの処理なのに、私のコードは for の中に if が入り、さらにその中に if が入り...と、まるで迷路のようになっていました。 そんな私に先輩が教えてくれたのが、Java 8から導入された革命的な機能、「Stream API」でした。 「これを使えば、その10行のコード、1行になるよ」 半信半疑で書き直してみた時の衝撃は、今でも忘れられません。魔法のようにコードが短く、そして美しくなったのです。 今日は、当時の私のような「forループ職人」を卒業し、モダンでスマートなJavaを書けるようになるための強力な武器、Stream APIの使い方を伝授します。 🌊 Stream APIとは? データの「流れ」を作る Stream APIとは、データの集まりを、まるで工場のベルトコンベアに乗せて流れる「部品のストリーム(流れ)」のように扱うための仕組みです。 このベルトコンベアの上で、私たちは様々な加工(処理)を行うことができます。 フィルター工程 (filter): 条件に合わない部品を流れから弾く。 マップ工程 (map): 流れてくる部品を、別の形の部品に変換する。 集計工程 (collect): 加工が終わった部品を箱に詰めて、完成品(新しいリスト)にする。 この「何をしたいか(宣言的)」をメソッドチェーンで繋げていくだけで、複雑なデータ処理が驚くほどシンプルに記述できるのです。 🛠️ 実践!forループをStream APIで書き換える 百聞は一見に如かず。実際に、よくあるデータ処理をStream APIでリファクタリングしてみましょう。 ここに、商品(Product)のリストがあるとします。 class Product { String name; int price; boolean isInStock; // (コンストラクタやゲッターは省略) } List products = List.of( new Product("Laptop", 120000, true), new Product("Mouse", 5000, false), new Product("Keyboard", 8000, true), new Product("Monitor", 35000, true) ); お題:「在庫があり、かつ値段が1万円以上の商品の名前だけをリストで欲しい」 Before: 伝統的なforループ(私が昔書いていたコード) 従来の書き方だと、まず空のリストを用意し、forループの中でif文を使って条件判定をし、条件に合えばリストに追加する…という手順になります。 List expensiveInStockProductNames = new ArrayList<>(); for (Product p : products) { // ネストが深くなり、読むのが辛い... if (p.isInStock()) { if (p.getPrice() >= 10000) { expensiveInStockProductNames.add(p.getName()); } } } System.out.println(expensiveInStockProductNames); // => [Laptop, Monitor] 「どのように(How)」処理するかが細かく書かれており、パッと見で何をしているか分かりにくいですね。 After: モダンなStream API Stream APIを使うと、「何を(What)」したいのかを直接的に表現できます。 import java.util.stream.Collectors; List expensiveInStockProductNames = products.stream() // 1. リストをストリーム(流れ)に変換 .filter(p -> p.isInStock()) // 2. 在庫があるものだけをフィルタリング .filter(p -> p.getPrice() >= 10000) // 3. 価格が1万円以上のものをフィルタリング .map(p -> p.getName()) // 4. Productオブジェクトを、名前(String)に変換 .collect(Collectors.toList()); // 5. 結果を新しいリストとして集計 System.out.println(expensiveInStockProductNames); // => [Laptop, Monitor] 💡 ラムダ式 p -> ... とは? p -> p.isInStock() のような矢印を使った書き方はラムダ式と呼ばれ、メソッドの引数として渡せる「使い捨ての小さな無名関数」です。filterメソッドは、このラムダ式を「判定ルール」として受け取り、リストの各要素(p)に対してそのルールを適用してくれるのです。 どうでしょうか? for も if も消え去り、まるで処理の仕様書をそのままコードに落とし込んだかのような、宣言的で美しいコードになりました。 まとめ:Stream APIがもたらすもの Stream APIは、単にコードを短くするためのテクニックではありません。 高い可読性: 処理の流れが上から下へ一直線になり、何をしているのかが直感的に理解できる。 バグの減少: ループカウンタの管理ミスや、条件分岐のネストによる複雑化といった、バグの温床を根本から排除できる。 最初はラムダ式の見慣れない書き方に戸惑うかもしれませんが、filter(絞り込み)、map(変換)、collect(集計)という3つの基本操作を覚えるだけで、あなたのデータ処理能力は飛躍的に向上します。 ぜひ、あなたのコードの中にある古き良きforループを、Stream APIでリファクタリングしてみてください。その一行が、あなたを「Java初心者」から「中級者」へと導く、大きな一歩となるはずです。 プログラミング学習に必須ツール! 記事で紹介したコードがよく分からなかったり、ご自身のコードについてもっと知りたい場合は、AIコード解説ツールが便利です。コードを貼り付けるだけで、AIが日本語で分かりやすく解説します。 AIコード解説ツールを使ってみる →