Java8から追加されたラムダ式についてまとめてみた。
Java8から追加されたラムダ式に触れる機会が増えてきたので、ここらへんで自分の知識をまとめておきたいと思う。
まずラムダ式とはなにか。関数型インターフェース(1つのインターフェースに実装が必要なメソッドを1つだけ持つインターフェース)に対して、以下のような形式で記述する文法である。
(引数) -> {処理};
では、実際にどのようになるか見てみよう。まずはjava.util.function.Functionインタフェースに対して、ラムダ式を使わずに匿名クラスで記述した場合。
public void testMethod() { Function<Integer, Double> function = new Function<Integer, Double>() { @Override public Double apply(Integer t) { return (double) t / 2; } }; System.out.println(function.apply(1)); }
では、上記をラムダ式で記述するとどのようになるか。
public void testMethod() { Function<Integer, Double> function = (Integer t) -> { return (double) t / 2; }; System.out.println(function.apply(1)); }
慣れないと分かりにくいが、匿名クラスの作成やメソッド部分が省略され、ずいぶん記述量が減った。
ここから若干、駆け足で説明したいと思おう。まずは引数の型は定義されているため、記述を省略できる。(ここではジェネリックス型なので左辺で定義されている。ジェネリックス型以外であればインタフェースに定義済みである。)
public void testMethod() { Function<Integer, Double> function = (t) -> { return (double) t / 2; }; System.out.println(function.apply(1)); }
さらに引数が一つであれば括弧()が省略できる。
public void testMethod() { Function<Integer, Double> function = t -> { return (double) t / 2; }; System.out.println(function.apply(1)); }
また戻り値が一つであれば return を省略できる。
public void testMethod() { Function<Integer, Double> function = t -> (double) t / 2; System.out.println(function.apply(1)); }
最初の匿名クラスの場合と比較してみてほしい。たった一行でインターフェースの実装が完了してしまった!!
これがラムダ式の力である。
もちろん慣れるまで意味を把握しにくいかもしれないが、この記述量の削減には素晴らしいものがある!
それにJava8から追加された「Stream API」ではラムダ式が多用されるため、
ぜひとも早く慣れて使いこなせるようになっておいたほうがいい。
最後にいくつか補足を付け加える。
まずは引数がない場合、どのようになるか。答えは ()-> {処理}; となる。
ここではjava.util.function.Supplierについて例を記載する。
public void testMethod_Supplier() { Supplier<String> supplier = () -> "supplier"; // supplierと表示。 System.out.println(supplier.get()); }
またメソッド参照ができるので、このような記載も可能。
ここではjava.util.function.Consumerについて例を記載する。
public void testMethod() { Consumer<String> consumer = System.out::println; // consumerと表示。 consumer.accept("consumer"); }