気軽に楽しくプログラムと遊ぶ

自分が興味があってためになるかもって思う情報を提供しています。

Java8 ラムダ式でよく利用する関数型インターフェース

関数型インターフェースとは?

  • 単一メソッドを持つインターフェース群
  • ラムダ 式で利用するのに都合がいい
  • 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のTはメソッドの引数の型を指定する。
メソッドは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は、引数が1つで処理結果を返却しない場合のラムダ式に用いる。

Predicate

PredicateのTはメソッドの引数の型を指定する。 メソッドは boolean test(T)を使って、定義した処理に引数を渡して、結果を返却する。

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は、引数が1つでbooleanを返却する場合のラムダ式に用いる。