Javaのラムダ式の読み解き方とは?方法をご紹介!

- システム
エンジニア - Javaのラムダ式の読み解き方ってどのような方法なのですか?
- プロジェクト
マネージャー - Java8以前のバージョンまでの記法を省略できる構築方法のことです。
Javaのラムダ式とは
Javaのラムダ式とはJava8からの構文です。例をあげると () -> System.out.println(“”Howdy, world!””) といった構文がラムダ式です。初めて目にする方、慣れていない方もいるかと思います。そんな方を対象にJavaラムダ式の読み解き方、覚え方を解説していきます。
ラムダ式とは何か
ラムダ式とは何かと聞かれれば、関数型インターフェースの実装をJava8より前のバージョンまでの記法より省略できる構文、と答えることができます。実際のコードをOracleの公式ページから引用すると以下の例があります。
1
2
3
4
5
6
7
8
9
10
11
|
//Java8より前バージョンでの記法
public class Lambdas {
public static void main(String... args) {
Runnable r = new Runnable() {
public void run() {
System.out.println(""Howdy, world!"");
}
};
r.run();
}
}
|
1
2
3
4
5
|
//Java8以降のラムダ式を使った記法
public static void main(String... args) {
Runnable r2 = () -> System.out.println(""Howdy, world!"");
r2.run();
}
|
ラムダ式では随分とシンプルになりました。この2つのプログラムが同一であるとは、どのように読み解けばよいのでしょう。
読み解き方
ラムダ式を読み解くにはローカルクラス、無名クラス、そして関数型インターフェースについて知る必要があります。ローカルクラスと無名クラスはJava8より前のバージョンからあるJavaの機能ですが、簡単におさらいしていきましょう。
ローカルクラス
ローカルクラスとはメソッド内に定義したクラスのことです。メソッド内でのみ有効となります。
1
2
3
4
5
6
7
8
9
10
11
|
public static void main(String... args) {
class LocalClass{
public void HelloWorld() {
System.out.println(""Howdy, world!"");
}
}
LocalClass localClass = new LocalClass();
localClass.HelloWorld();
}
|
無名クラス
無名クラスとはその名の通り名前のないクラスです。匿名クラスともいいます。主にインターフェースの実装時に名前付けしたクラスとして抽出するまでもない場合に利用されます。
1
2
3
4
5
6
|
//Runnable自体はインターフェースですが、new演算子 + インターフェース() + {} の中に実装することで無名クラスとして定義できます
Runnable r = new Runnable() {
public void run() {
System.out.println(""Howdy, world!"");
}
};
|
ラムダ式
改めてラムダ式について見ていきましょう。ラムダ式とは関数型インターフェースの実装を省略して記載できる式のことでした。一旦関数型インターフェースについては置いておき、ラムダ式がどこを省略しているか見ていきます。
1
2
3
4
5
6
7
8
9
10
|
//ラムダ式でない
Runnable r = new Runnable() {
public void run() {
System.out.println(""Howdy, world!"");
}
};
//ラムダ式で記載
Runnable run = () -> System.out.println(""Howdy, world!"");
|
まずnew Runnable() {}の記載がなくなっています。そしてpublic void run() {}も見当たりません。このように型の省略、実装するメソッド定義の省略を行えるのがラムダ式の特徴です。
ではどのようにして省略された情報をコンパイラが知るのでしょうか。
型の省略
型を省略した場合、代入される変数の型から推論する仕組みになっています。先程の例ではRunnable rのRunnableから推論されています。この機能を型推論といいコンパイラが自動で判別しています。
メソッド定義の省略
型推論からどの型のインターフェースであるかは推論されました。しかしそのインターフェース内のどのメソッドをオーバーライドしているかは推論できません。
そのため、ラムダ式が使えるインターフェースには抽象メソッドが1つだけ、という制約があります。Runnableのインターフェース定義をみると以下のようになります。
1
2
3
4
5
6
7
8
|
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface {@code Runnable} is used
* to create a thread, starting the thread causes the object's
* {@code run} method to be called in that separately executing
* thread.
*
|
* The general contract of the method {@code run} is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }
関数型インターフェース
ここで関数型インターフェース、という定義を見ていきましょう。関数型インターフェースとは抽象メソッドが1つだけのインターフェースのことです。
つまり、ラムダ式が使用できるインターフェースともいえます。インターフェースの定義時に明示的に関数型インターフェースである、と示すには前述のように@FunctionalInterfaceというアノテーションをクラスにつけます。
次項ではJava8から新たに提供されている、関数型インターフェース4つを紹介します。
Function
Function<T, R>のインターフェース定義です。メソッドは R apply(T) を持ちます。<T,R>は実装者が定義できる型です。実装するメソッドは引数としてTを受け取り、Rを返します。ここでは単純にString型の引数のレングスを返すFunctionを見ていきましょう。
1
2
|
Function<String, Integer> func = (str) -> str.length();
System.out.println(func.apply(""ほげ"")); //->2が出力される
|
Consumer
Consumer<T>のインターフェース定義です。メソッドはvoid accept(T)を持ちます。<T>は実装者が定義できる型です。実装するメソッドは引数としてTを受け取りますが、結果は返しません。
ここでは単純にString型の引数を、標準出力して終えるConsumerを見ていきましょう。
1
2
|
Consumer cons = (str) -> System.out.println(str);
cons.accept(""consumer""); // -> consumerが出力される
|
Predicate
Predicate<T>のインターフェース定義です。メソッドは boolean test(T t) を持ちます。<T>は実装者が定義できる型です。実装するメソッドは引数としてTを受け取り、boolean値を返します。
ここでは単純にInteger型の引数を受け、3より大きい場合にtrueを、それ以外のときにfalseを返すPredicateを見ていきましょう。
1
2
|
Predicate pred = (num) -> num > 3 ? true : false;
System.out.println(pred.test(1)); // -> falseが出力される
|
Supplier
Supplier<T>のインターフェース定義です。メソッドは T get() を持ちます。<T>は実装者が定義できる型です。実装するメソッドは、引数としては何も受け取りませんが、Tを返します。ここでは単純にInteger型の値を返すSupplierを見ていきましょう。
1
2
|
Supplier supp = () -> 1;
System.out.println(supp.get()); // -> 1が出力される
|
- システム
エンジニア - ラムダ式には、さまざまな手法があるのですね。
- プロジェクト
マネージャー - これらを取り入れることで、Javaの機能を使いこなすことが出来るでしょう。
Javaのラムダ式を理解しよう
この記事ではJavaにおけるラムダ式の読み解き方をご紹介しましたが、いかがでしたでしょうか。ラムダ式とは関数型インターフェースの実装を、Java8より前のバージョンまでの記法より省略できる構文として見てきました。
ローカルクラス・無名クラスを復習し、関数型インターフェースを知り、ラムダ式の理解ができたのではないでしょうか。Javaの機能は数多くあります。1つずつ知識を広げて自由にコーディングできるようになっていきましょう。
FEnetJava・Javaコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


Java新着案件New Job
-
官公庁向け業務システム開発/Java/東京都千代田区/【WEB面談可】/テレワーク
月給39万~44万円東京都千代田区(永田町駅) -
販売管理システム開発/Java/東京都中央区/【WEB面談可】/テレワーク
月給49万~55万円東京都中央区(京橋駅) -
生命保険会社向けシステム開発/Java/東京都千代田区/【WEB面談可】/テレワーク
月給42万~48万円東京都千代田区(大手町駅) -
社会保険システムのパッケージ開発/Java/東京都港区/【WEB面談可】/テレワーク
月給42万~48万円東京都港区(新橋駅) -
金融機関向けシステム更改/Java/東京都江東区/【WEB面談可】/テレワーク
月給46万~51万円東京都江東区(豊洲駅) -
大手通信会社者向けWebシステム改修/Java/東京都港区/【WEB面談可】/テレワーク
月給42万~48万円東京都港区(品川駅)