[java8]java8関数型インターフェースとラムダと高階関数さわり

関数型インターフェース

めっちゃさわりだけですが、java8はじめてさわったときからの
メモを少し整えたもの

関数型インターフェースである条件

定義されている抽象メソッドが1つであること
staticメソッドや、defaultメソッドは条件の対象ではない

この条件を満たせば自動的に関数型インターフェースとして
認識され利用することができるが、コンパイラに明示的に
関数型インターフェースであることを示すために@FUnctionalInterfaceアノテーションをつけることで、関数型インターフェースの
条件を満たしていない場合にコンパイルエラーを出してくれるようにすることができる。

関数型インターフェースのインスタンスはラムダ式で記述することができる。
(無名クラスをnewしてoverrideしてー、みたいなのが不要になった。)

標準関数型インターフェースのうち代表的なもの

多用するであろうStreamとOptionalで利用されているもの+αをあげてみました。

  • Function
    任意の型を受け取り、任意の型を返す T -> R
  • Function
    任意の型Tのインスタンスを2つ受け取り、任意の型を返す (T,T) -> R
  • Predicate
    任意の型を受け取り、booleanを返す(条件判定) T -> boolean
  • Consumer
    任意の引数を受け取り値を返さない(処理を行う。主に副作用を伴う処理を担う) T -> void
  • Supplier
    引数なしで任意の型の値を返す(供給する) () -> T
  • Comparator
    型Tの2つのインスタンスを受け取って、整数を返す(比較する) (T,T) -> int
  • UnaryOperator
    型Tのインスタンスを受け取って、型Tのインスタンスを返す(一項演算子) T -> T
    特殊なFunction型だと言い換えられる。(Function)
  • BinaryOperator
    型Tの2つのインスタンスを受け取って、型Tのインスタンスを返す(二項演算子) (T,T) -> T
    特殊なBiFunction型だと言い換えられる。(BiFunction)

OptionalやStreamAPIの各種メソッドの引数

  • [Stream,Optional] map, flatMap(Function)
  • [Stream] forEach(Consumer)
  • [Optional] ifPresent(Consumer)
  • [Stream] reduce(畳み込み BinaryOperator)
  • [Stream] allMatch,anyMatch, filter(Predicate)
  • [Stream] sorted, min, max(Comparator)
  • [Optional] orElseGet(Supplier)

こうやって見ると納得ですね。それぞれの役割。

ミュータブルな値

ラムダ式内部では再代入されているような変数を利用することができません。(コンパイルエラー)

値はfinalでイミュータブルになっている、もしくは再代入されていないことが明確な
実質的にイミュータブルな値のみが利用できます。

これはコンパイルエラーになります。
ではどうしたらよいのでしょう・・・。

こんな感じ。
再代入はさせたいけど、ラムダ式実行中に変更しないようなものであれば
ラムダ式前でfinalで新しい変数宣言して、そこに代入させればOKかな・・・?
scalaでvalのみで99%くらいどうにかなってるので、javaも必要なとき以外はfinalで
いいじゃん、と、あんまりjava知らないけど思ってる

例外はどう扱うか

ラムダ式も結局のところ通常のメソッドと同じで、ラムダ式内で例外が起きれば
それは、ラムダ式を呼び出している関数の例外ではなく、ラムダ式が投げた例外になります。

なので、チェック例外はラムダの外でcatchしないとコンパイルエラーになります。
ラムダ内で例外を完結させる、またはラムダ外で例外をキャッチする必要があります。

参考までに、こちらでは

Webアプリケーションなど、処理が終了してもプロセスが終了しないようなサーバーでは、
どちらかというと、ラムダ内で例外は発生させないか、発生しても外側に投げない仕組みにした方がよいでしょう。

とあります。
Eitherが欲しいなぁ・・・・。
と思ったらまぁこんな感じでやってる人いました(試してはいません)

(stackoverflow) Is there an equivalent of Scala’s Either in Java 8?

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です