関数型インターフェースとは?
- 単一メソッドを持つインターフェース群
- ラムダ 式で利用するのに都合がいい
- SE8からjava.util.functionパッケージに追加された
ラムダ式を引数として取る場合に、関数型インターフェースを指定して受け取る。
ラムダ式の種類毎に用意された入れ物が関数型インターフェースとも言える。
// 例として、filter()は関数型インターフェースを引数に取る numbersList.stream().filter((i) -> { return i > 0; })
関数型インターフェースとして使用頻度の高いFuction、Consumer、Predicateを見ていく。
Function<T,R>
Function<T,R>のTはメソッドの引数の型、Rは戻り値の型を指定する。
メソッドはR apply(T)を使って、定義した処理に引数を渡して、結果を返却する。
// Functionにラムダ 式(メソッドオブジェクトのようなもの)を代入 Function<Interger, Integer> calcPlusOne = (i) -> { return i + 1 }; // calcPlusOneを使ってみる Integer result = calcPlusOne.apply(1); // result = 2
Function<T,R>を引数に取るStreamAPIのメソッドmap
ListString impNum = numbersList.stream().filter((i) -> { return i >= 0; }) .map((i) -> { return "*" + i + "*"; }) .forEach((s) -> { System.out.print(s + " "); }); // *2* *0* *8*
Function<T,R>は、引数が1つで処理結果を返却したい場合のラムダ式に用いる。
Consumer
Consumer
メソッドはvoid accept(T)を使って、定義した処理に引数を渡して、結果を返却する。
Consumer<String> greeting = (name) -> { System.out.println(name + "さん、おはようございます。"); }; greeting.accept("太郎"); // 太郎さん、おはようございます。
Consumerを引数に取るStreamAPIのメソッドforEach
numbersList.stream().forEach((i) -> { System.out.print(i + " "); }); // Eachは要素の数だけ繰り返す。
Consumer
Predicate
Predicate
Predicate<T> checkBigNum = (num) -> { return num > 10000} boolean result = checkBigNum(10); // result = false
Predicateを引数に取るStreamAPIのメソッドfilter
// numbersListに-1 と2と8あり numbersList.stream().filter((i) -> { return i > 0; }) // 負の数を除外 .forEach((i) -> { System.out.print(i + " "); }); // 2 8
Predicate