ラムダ式 / (x) -> x * 2
ラムダ式は関数(メソッド)を簡潔に表現する記法です(Java 8以降)。関数型インターフェースとは、抽象メソッドを1つだけ持つインターフェースのことです。ラムダ式はこのインターフェースの実装を簡潔に書く方法です。メソッドを引数として渡したり、関数型インターフェースの実装を1行で書いたりできます。メソッド参照(::)と組み合わせるとさらに簡潔になります。
構文
// ラムダ式の基本構文です
(引数) -> 式
// 処理が複数行の場合はブロックを使います
(引数) -> {
// 複数の処理
return 値;
}
// 引数が1つの場合は括弧を省略できます
x -> x * 2
// メソッド参照の種類です
クラス::staticメソッド // 例: Integer::parseInt
インスタンス::インスタンスメソッド // 例: str::toUpperCase
クラス::インスタンスメソッド // 例: String::length
クラス::new(コンストラクタ参照) // 例: ArrayList::new
// Comparator.comparing() でソートキーを指定します
list.sort(Comparator.comparing(o -> o.getName()));
list.sort(Comparator.comparing(Person::getName));
主な使用場面一覧
| 使用場面 | ラムダ式の例 |
|---|---|
| Runnableの実装 | () -> System.out.println("実行") |
| リストのソート | list.sort((a, b) -> a.compareTo(b)) |
| ストリームのfilter | stream.filter(x -> x > 0) |
| ストリームのmap | stream.map(x -> x * 2) |
| forEachの処理 | list.forEach(s -> System.out.println(s)) |
| メソッド参照(同上) | list.forEach(System.out::println) |
| Comparator.comparing() | Comparator.comparing(Person::getName) |
サンプルコード
sample_LambdaExample.java
import java.util.*;
class Person {
String name; int age; String favoriteSong;
Person(String n, int a, String s) { name = n; age = a; favoriteSong = s; }
String getName() { return name; }
int getAge() { return age; }
String getFavoriteSong() { return favoriteSong; }
}
class LambdaExample {
public static void main(String[] args) {
// ラムダ式でRunnableを実装します
Runnable r = () -> System.out.println("スレッドを実行しました。");
new Thread(r).start();
// リストを昇順にソートします
List<String> names = new ArrayList<>(List.of("孫悟空", "ベジータ", "ブルマ"));
names.sort((a, b) -> a.compareTo(b));
System.out.println(names); // 『[ブルマ, ベジータ, 孫悟空]』と出力されます。
// メソッド参照で同じ処理を書きます
names.sort(String::compareTo);
// Comparator.comparing() でフィールドを基準にソートします
List<String> words = new ArrayList<>(List.of("Vegeta", "Son Goku", "Krillin", "Bulma"));
words.sort(Comparator.comparing(String::length));
System.out.println(words); // 『[Bulma, Vegeta, Krillin, Son Goku]』と出力されます。
// メソッド参照でforEachを書きます
List<Integer> nums = List.of(1, 2, 3, 4, 5);
nums.forEach(System.out::println); // 各要素を出力します。
// 独自クラスでComparator.comparing()を使います
List<Person> people = List.of(new Person("ベジータ", 29, "CHA-LA HEAD-CHA-LA"), new Person("孫悟空", 23, "魔訶不思議アドベンチャー!"));
people.stream()
.sorted(Comparator.comparing(Person::getAge))
.forEach(p -> System.out.println(p.getName() + ": " + p.getFavoriteSong())); // 年齢昇順で出力されます。
}
}
LambdaExample.java
javac LambdaExample.java java LambdaExample スレッドを実行しました。 [ブルマ, ベジータ, 孫悟空] [Bulma, Vegeta, Krillin, Son Goku] 1 2 3 4 5 孫悟空: 魔訶不思議アドベンチャー! ベジータ: CHA-LA HEAD-CHA-LA
※ スレッドの出力タイミングは実行環境によって変わります。
概要
ラムダ式は関数型インターフェース(抽象メソッドを1つだけ持つインターフェース)の実装として使われます。匿名クラスに比べて格段に簡潔に書けます。
メソッド参照(::)はラムダ式をさらに短くした記法です。x -> x.toString() は Object::toString と同じ意味になります。ラムダ式の中から外部のローカル変数を参照するには、その変数が「実質的にfinal」(変更されない)である必要があります。
主な関数型インターフェースについては『Predicate / Function / Consumer / Supplier』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。