ラムダ式

概要

ラムダ式は,特定のメソッドを簡略化して書けるような文法で,Java 8から導入されました. 例えば,Strema API を用いて指定された数までの FizzBuzz を出力するプログラムを例に挙げて説明します. 以下のプログラムの runメソッドの filterメソッド,map メソッドに渡している v -> v % 2 == 1i -> Integer.toString() がラムダ式と呼ばれる書き方です.

public class OddNumbersStream {
    void run(String[] args) {
        return IntStream.rangeClosed(1, 50)
            .filter(v -> v % 2 == 1)
            .mapToObj(number -> Integer.toString(number))
            .collect(Collectors.joining(" "));
    }
    public static void main(String[] args) {
        new OddNumbersStream().run(args);
    }
}

これは,以下のようなメソッドが定義されており,その定義を省略して書いています.

    void run(String[] args) {
        return IntStream.
            .filter(int test(int v) {
                return v % 2 == 1;
            })
            .mapToObj(String apply(int number) {
                return Integer.toString(number);
            })
            .collect(Collectors.joining(" "));
    }

ラムダ式では,-> の前に引数を,後ろにメソッドの中身を書きます. メソッド名,引数の型,返り値の型が省略されています. また,-> の後ろのメソッドの中身が1つの式の場合はメソッド定義の波括弧({})とreturnが省略可能です.

書き方

(型 変数1, 型 変数2, ...) -> { メソッドの中身 }

ただし,以下のものが省略可能です.

ラムダ式の書き方いろいろ

省略しない場合

Function<Integer, String> fizzbuzzer = (Integer number) -> {
    if(number % 15 == 0)     return "FizzBuzz";
    else if(number % 3 == 0) return "Fizz";
    else if(number % 5 == 0) return "Buzz";
    return Integer.toString(number);
};

引数の型を省略

Function<Integer, String> fizzbuzzer = (number) -> {
    if(number % 15 == 0)     return "FizzBuzz";
    else if(number % 3 == 0) return "Fizz";
    else if(number % 5 == 0) return "Buzz";
    return Integer.toString(number);
};

引数の括弧を省略

Function<Integer, String> fizzbuzzer = number -> {
    if(number % 15 == 0)     return "FizzBuzz";
    else if(number % 3 == 0) return "Fizz";
    else if(number % 5 == 0) return "Buzz";
    return Integer.toString(number);
};

メソッドの切り出し

Function<Integer, String> fizzbuzzer = number -> {
    return fizzbuzz(number);
};

String fizzbuzz(Integer number) {
    if(number % 15 == 0)     return "FizzBuzz";
    else if(number % 3 == 0) return "Fizz";
    else if(number % 5 == 0) return "Buzz";
    return Integer.toString(number);
}

波括弧とreturnの省略

Function<Integer, String> fizzbuzzer = number -> fizzbuzz(number);

String fizzbuzz(Integer number) {
    if(number % 15 == 0)     return "FizzBuzz";
    else if(number % 3 == 0) return "Fizz";
    else if(number % 5 == 0) return "Buzz";
    return Integer.toString(number);
}

このような書き方は,これまでの Java の文法とは大きく異なるので,初見だと面食らうかもしれません. しかし,書き方が違うだけで行っていることは従来からと同じです. 慣れるまでは何を意味しているのかを確認しながら読み解いてください.

参考資料