前回の記事
ラムダ式ってなに?
にてScalaでのラムダ式の利用方法について書いた。
なので今回はJavaにもSE8からラムダ式が導入されたので全く同じ内容をJavaで再現してみたいと思う。
Javaでのラムダ式
Javaは関数型言語ではないのでラムダ式をすんなり書くことができない。
Javaでラムダ式を表現するには匿名クラスを利用した形になる。
SE8から関数型インターフェースと言われるインターフェースが用意された。
それらはjava.util.functionパッケージに属する。
これらを実装する形でラムダ式を表現するのが手っ取り早い。
今回はその中のConsumerインターフェースを利用して再現してみる。
Comsumerインターフェース
引数を1つ、戻り値なしのラムダ式を表現する際にはこのConsumerインターフェースを利用する。
ComsumerインターフェースはJavaAPIを確認すればわかるが型パラメータを利用して定義されている。
インターフェースConsumer
この型パラメータのTには、ラムダ式を表現する際の引数の型を指定する。
ラムダ式を記述する
では実際にラムダ式を記述していきたいと思う。
前回の記事で書いたラムダ式はInt型を受け取ってUnit型(void)を返すラムダ式だった。
それをJavaで書くとこうなる。
Consumer<Integer> lambda = (x) -> {System.out.println(x + 5);};
型パラメータにint型は指定できないため、Integer型とした。
これはConsumerインターフェースを実装した匿名クラスを定義し、lambdaという変数に格納している記述になるが実際裏ではどうなっているかというと、Consumerインターフェースに定義されているaccept(T t)メソッドをオーバーライドした形になる。
コードで書くと
Consumer<Integer> lambda2 = new Consumer<Integer>(){ public void accept(Integer t){ System.out.println(t + 5); } };
このように記述した状態と同じになる。
では前回と同様に、このラムダ式を受け取るメソッドを定義してみる。
ラムダ式を受け取るメソッドの定義
前回と同様、ラムダ式とInteger型の値を受け取るメソッドを定義する。
static void func(Consumer formula, int num){ formula.accept(num + 5); }
引数に受け取ったnumに5を加算し、それをラムダ式(formulaのaccept()メソッド)に引数として渡し処理させる。
それでは先ほど定義したラムダ式とIntegerの値を渡して処理させてみよう。
実際にラムダ式はacceptメソッドをオーバーライドしているのかを確認するため、両パターンの書き方をしたlambdaとlambda2を用意した。
(Lambda.java)
import java.util.function.*; class Lambda{ public static void main(String[] args){ Consumer<Integer> lambda = (x) -> {System.out.println(x + 5); }; Func.func(lambda, 5); Consumer<Integer> lambda2 = new Consumer<Integer>(){ public void accept(Integer t){ System.out.println(t + 5); } }; Func.func(lambda2, 10); } } class Func{ static void func(Consumer formula, int num){ formula.accept(num + 5); } }
実行結果は以下
username$ javac Lambda.java 注意:Lambda.javaの操作は、未チェックまたは安全ではありません。 注意:詳細は、-Xlint:uncheckedオプションを指定して再コンパイルしてください。 username$ java Lambda 15 20
今回は戻り値なし、引数1つのラムダ式を定義したが、もちろん戻り値ありのものも定義できる。
Functionインターフェースを利用すれば引数1つ、戻り値ありのラムダ式を表現できる。
その他にもたくさんの方法、たくさんのインターフェースが用意されているが、今回はConsumerインターフェースに焦点を当ててみた。
コメント