Java 逆引き集 | forEach とラムダの基本(簡単な処理) - 可読性向上

Java Java
スポンサーリンク

forEach とラムダって何者か(「ちょっとした処理」を読みやすく書く道具)

forEach とラムダ式は、「コレクションの全要素に対して簡単な処理をする」場面で、コードを短く・読みやすく書くための道具です。 従来の for 文でも同じことはできますが、ラムダを使うと「何をしたいか」にフォーカスした書き方になり、ノイズが減ります。 まずは「拡張 for 文との違い」を意識しながら、基本形を押さえていきましょう。

拡張 for 文との比較から入る

拡張 for 文の基本形

まず、従来の「拡張 for 文」で全要素を処理する形を確認します。

List<String> names = List.of("Taro", "Hanako", "Jiro");

for (String name : names) {
    System.out.println(name);
}
Java

「names の中身を先頭から順番に取り出して、name に入れて処理する」という、とても素直な書き方です。 これに対して、forEach とラムダを使うと、次のように書けます。

names.forEach(name -> System.out.println(name));
Java

どちらも「全要素を表示する」という意味ですが、forEach 版は「names に対して、要素ごとにこの処理をしてね」と、 “処理の中身”だけをラムダ式として渡している形になります。

ラムダ式の基本形を分解する

「引数」→「矢印」→「処理」

ラムダ式の基本形は、こういう見た目です。

name -> System.out.println(name)
Java

これを分解すると、

name … 1件分の要素を受け取る引数 -> … 「この引数に対して、右側の処理を実行する」という矢印 System.out.println(name) … 実際にやりたい処理

という構造になっています。 拡張 for 文で書くときの「for (String name : names) の name」が、そのままラムダの引数になっているイメージです。

もう少し複雑な処理でも、基本は同じです。

names.forEach(name -> {
    String upper = name.toUpperCase();
    System.out.println("NAME: " + upper);
});
Java

ここでは、ラムダの右側を { ... } で囲んで、複数行の処理を書いています。 「1件分の要素を受け取って、ブロック内で好きな処理をする」という形が見えればOKです。

forEach とラムダで「意図が読みやすくなる」例

ログ出力の簡単な処理

例えば、ユーザーIDの一覧をログに出したいとします。

List<Integer> userIds = List.of(101, 102, 103);
Java

拡張 for 文ならこうです。

for (Integer id : userIds) {
    System.out.println("userId=" + id);
}
Java

forEach とラムダを使うと、こう書けます。

userIds.forEach(id -> System.out.println("userId=" + id));
Java

「userIds に対して、1件ずつこの処理をする」という構造が、 forEach というメソッド名とラムダの形から、かなりストレートに伝わります。

条件付きの処理も書ける

ラムダの中身は普通の Java コードなので、if 文も書けます。

userIds.forEach(id -> {
    if (id >= 102) {
        System.out.println("VIP userId=" + id);
    }
});
Java

「全件を回しながら、条件を満たすものだけログに出す」という意図が、 拡張 for 文と同じように書けつつ、forEach によって“全件処理している”ことが明示されます。

ラムダ式で意識してほしい「簡単さ」のライン

「1行〜数行の“ちょっとした処理”」に向いている

ラムダ式は、「1行〜数行の簡単な処理」を書くときに特に威力を発揮します。

names.forEach(name -> System.out.println(name.toUpperCase()));
Java

このくらいなら、拡張 for 文よりも「何をしたいか」が一目で分かります。 一方で、ラムダの中が長くなりすぎると、逆に読みづらくなります。

names.forEach(name -> {
    // ここに10行以上の複雑な処理がずらっと並ぶ…
});
Java

こうなってきたら、「ラムダの中身を別メソッドに切り出す」方が読みやすくなります。

names.forEach(this::printProcessedName);

private void printProcessedName(String name) {
    // 複雑な処理をここに書く
}
Java

「ラムダは簡単な処理」「複雑になったらメソッド参照や普通のメソッド」に切り替える、 という感覚を持っておくと、コードの可読性を保ちやすくなります。

まとめと小さな練習

forEach とラムダは、「コレクションの全要素に対して簡単な処理をする」ための、読みやすい書き方です。 拡張 for 文と同じことができつつ、「全件処理している」「1件分の要素に対してこの処理をする」という意図が、コードから直接伝わりやすくなります。

練習として、

List<String> の名前一覧を作り、拡張 for 文版と forEach+ラムダ版の両方で「大文字にして表示する」コードを書いてみる List<Integer> の点数一覧から、60点未満だけ「不合格」と表示する処理を、ラムダの中に if を書いて実装してみる

という2つをやってみると、「ラムダの基本形」「forEach の使いどころ」がかなり体に入ってくるはずです。

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