
このページでは直感的には中々理解しづらいJavaのラムダ式について解説します。
ラムダ式を理解するうえでは、その前段階として「ローカルクラス」や「匿名クラス」がどういうものかをおさらいすると整理しやすいです。それらを学ぶ流れの中で頭の中を整理すると、なぜラムダ式が生まれたのかも自然にわかります。このページでは、まずローカルクラスと匿名クラスをざっくり紹介し、最後にラムダ式へとつながるイメージを整理していきます。
【前提その1】ローカルクラス (Local Class)
ローカルクラスは、その名の通り「メソッドの中」で定義されるクラスです。通常のクラスはフィールドやメソッドの外側に定義しますが、ローカルクラスはメソッド内のローカル変数のように「メソッドブロックの中」で定義されます。
サンプルコード メソッド内でクラスを定義
public void doSomething() { // メソッド内でクラスを定義 class LocalPrinter { public void print(String message) { System.out.println("LocalPrinter: " + message); } } // ここでLocalPrinterを使う LocalPrinter printer = new LocalPrinter(); printer.print("Hello, Local Class!"); }
【前提その2】匿名クラス (Anonymous Class)
匿名クラスは、名前をつけないままクラスを定義して、その場でインスタンスを生成 できる仕組みです。
インターフェースや抽象クラスを “その場で” 実装したいときに使われます。
new 抽象クラスまたはインターフェース() { // クラスの実装 (メソッドのオーバーライド、フィールドの定義など) };
サンプルコード 匿名クラスを使ってインターフェースを実装
public void setListener() { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("ボタンがクリックされました"); } }); }

匿名クラス (Anonymous Class)は感覚的にピンとこない方も多いのでここで補足します。
まずは通常の「クラス定義 + インスタンス生成」をおさらいしましょう。ふつうクラスを使うときは、ざっくりこんな流れです。
1.クラス定義
class MyWorker implements Runnable { @Override public void run() { System.out.println("Hello from MyWorker!"); } }
2.インスタンス生成 + 呼び出し
MyWorker worker = new MyWorker(); worker.run(); // => "Hello from MyWorker!"

これが通常の使い方ですよね。しかし、毎回クラス名 MyWorker
をつけてわざわざファイルを作るほどでもない「ちょっとした実装を、その場でパッと書きたい」ことがあります。
ポイント 「匿名クラス」はクラス定義とインスタンス化を同時にやる
匿名クラスは、以下のように クラス名を持たないまま 、クラス定義とインスタンス生成をセットにして書くやり方です。
Runnable worker = new Runnable() { @Override public void run() { System.out.println("Hello from Anonymous Class!"); } };
呼び出しは通常と同じで、worker.run();
とすればOK。「Runnable
を実装した“何かのクラス”」をその場で作り、そのインスタンスを worker
に代入しているイメージです。
「匿名クラス」の課題とラムダ式の登場
匿名クラスは「一度きりの処理」を書く際に非常に便利でした。しかし、次第に下記のような「冗長さ」が目立つようになりました。
- 記述が長い
- インターフェース名を書き、
new
して{ ... }
でメソッドをオーバーライドする、という部分がどうしてもかさばる。
- インターフェース名を書き、
- メソッド名を書く必要がある
actionPerformed
とか、run
とか、インターフェースで決められたメソッド名を明示的に書く必要がある。
- 「処理」だけ書きたいのに、構文が多い
- “やりたい処理” は「ボタンがクリックされたら、コンソールに文字を出す」という一行の処理だけなのに、記述が散らばる。
このようなニーズをよりシンプルに実現するために生まれたのが ラムダ式 です。「匿名クラス+1メソッド」という状況を、もっと短い構文で書けるようにしたもの、と考えるとイメージがつかみやすいでしょう。
ラムダ式へつながるイメージ
匿名クラスからラムダ式へ
サンプルコード 匿名クラス (Java 8以前の書き方)
button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("ボタンがクリックされました"); } });
サンプルコード ラムダ式 (Java 8以降の書き方)
button.addActionListener(e -> { System.out.println("ボタンがクリックされました"); });
ラムダ式のための「関数型インターフェース」
ラムダ式を使えるのは、抽象メソッドを1つだけ持つインターフェース (関数型インターフェース) がある場合に限られます。ActionListener
は actionPerformed
メソッドだけのインターフェースなので、ラムダ式で表せるわけです。
Javaのラムダ式:まとめ
- ローカルクラス
- メソッドの中でクラス定義をする機能。
- 小さな補助的クラスをメソッド内だけで完結して書くときに便利。
- 匿名クラス
- 名前をつけずにクラスをその場で定義→即インスタンス化する機能。
- 一度きりの実装を簡潔に書く場面で使うが、実際には“クラスの定義+メソッドのオーバーライド”が冗長になりがち。
- ラムダ式
- 「匿名クラスで1メソッドしか実装しないケース」をもっと短く書くために導入。
- 関数型インターフェース (抽象メソッド1つのみ) に対応。
- コードの簡潔化・読みやすさ向上に大いに貢献。
ローカルクラスや匿名クラスは、「その場限りのクラスやメソッド実装を手軽に書きたい」という欲求から生まれましたが、さらに一歩進んで「メソッド(=処理のかたまり)だけをピンポイントに書きたい」という場合に、ラムダ式が非常に強力に機能します。特にJava 8以降はラムダ式とStream APIを併用して「コレクションを扱う処理」を一気に書きやすくすることができるようになり、現代Javaのスタンダードな書き方として定着しています。