ラムダ式は関数型インタフェースの実装匿名クラスを記述する簡易記法になる。
基本的な構文はつぎのようになる。
(引数) -> { 処理 }
ラムダ式の引数は、実装する関数型インタフェースのメソッドの引数と同じになる。また、処理の部分は、メソッドの本体を記述する。
たとえば、以下に示すIntAdderインタフェースの場合、インタフェースが定義しているaddメソッドの引数はintの引数が2つある。したがって、ラムダ式で もint引数を2つ記述する。
interface IntAdder {
int add(int x, int y);
}
// ラムダ式の引数はaddメソッドと同一
IntAdder adder = (int x, int y) -> { return x + y; };
ジェネリクスのパラメータで引数の型が決まる場合も、同様となる。
たとえば、Comparatorインタフェースのcompareメソッドの引数の型は、ジェネリクスのパラメータによって決まる。このような場合も、ラムダ式で記述す ることができる。
Comparator<Integer> comparator = (Integer x, Integer y) -> { return x - y; };
引数がないメソッドの場合、カッコだけを記述する。
Runnable runnable = () -> { doSomething(); };
ラムダ式では引数の型を省略することができる。省略した型は、型推論が行われ、コンパイル時に補完される。
ただし、型を省略する場合、すべての引数の型を省略する必要がある。
// OK
IntAdder adder1 = (int x, int y) -> { return x + y; };
// すべての引数の型の省略はOK
IntAdder adder2 = (x, y) -> { return x + y; };
// 一方だけの型の省略はNG
IntAdder adder3 = (int x, y) -> { return x + y; };
引数が1つのメソッドの場合、型を省略することに加え、カッコも省略することがでる。ただし、カッコを省略できるのは、型を省略した時だけとなる。
// OK
Consumer<String> consumer1 = (String text) -> { System.out.println(text); };
// OK
Consumer<String> consumer2 = (text) -> { System.out.println(text); };
// 型を省略した場合、カッコの省略もOK
Consumer<String> consumer3 = text -> { System.out.println(text); };
// 型を省略していないのでNG
Consumer<String> consumer4 = String text -> { System.out.println(text); };
メソッドの本体は波カッコで記述する。しかし、メソッドが1行で表せる場合、波カッコを省略できる。
// OK
Consumer<String> consumer1 = text -> { System.out.println(text); };
// 式が1つなので波カッコの省略がOK
Consumer<String> consumer2 = text -> System.out.println(text);
メソッドが1行で戻り値がある場合、returnを省略できる。この場合、式の評価結果が戻り値に使用される。
なお、メソッドが1行で戻り値がある場合は、波カッコもしくはreturnの一方だけを省略することはできません。常に両方を省略する必要があります。
// OK
Comparator<Integer> comparator1 = (x, y) -> { return x -y; };
// 波カッコとreturnの省略はOK
Comparator<Integer> comparator2 = (x, y) -> x -y;
// 波カッコだけの省略はNG
Comparator<Integer> comparator3 = (x, y) -> return x -y;
// returnだけの省略もNG
Comparator<Integer> comparator4 = (x, y) -> { x -y; };