こんにちは!ISAMU(@burlesca_isa)です!
今回の対象読者は
- Javaのラムダ式の書き方を詳しく学びたい方
※この記事を読む前にこちらの記事を読むことをおすすめします。
[nlink url=”https://kajirinyo.com/java_course_27/”]Javaのラムダ式の書き方を詳しく解説します
ラムダ式とはインターフェースを実装するインスタンスを返す式のことです。
ラムダ式を使用することでポリモフィズムを手軽に利用できるようになります。
基本的にはメソッドの引数で利用します。
ラムダ式と匿名クラスは同じもの
匿名クラスはクラスの宣言とインターフェースを実装したインスタンスの作成を一つの式で表すことができます。
匿名クラスを簡単に書けるようにしたものがラムダ式です。
匿名クラスはプログラムが冗長になってしまいますが、
匿名クラスをラムダ式に書き換えることで可読性が高まります。
まずは匿名クラスのサンプルコードを示します。
出力結果
===============200000円以上のギターを出力===============
[メーカー] : ギブソン [価格] : 200000円
[メーカー] : テイラー [価格] : 340000円
===============メーカーがテイラーのギターを出力===============
[メーカー] : テイラー [価格] : 340000円
プログラムの説明
このサンプルは
- 200000万円位上のギターを出力する
- メーカー名がテイラーのギターを出力する
という匿名クラスを作成し、
printメソッドに匿名クラスを引数で渡して出力するというプログラムです。
関数型インターフェースはPredicateを使用しています。
Predicateはboolean値を返すときに使用する関数型インターフェースで、
test()抽象メソッドを持っています。
printメソッドにPredicate型の匿名クラスを引数として渡すことで、
printメソッド内のif文の条件式を匿名クラスの条件式で判定しています。
printメソッドの引数にp_priceを渡せば200000円以上のギター、
p_nameを渡せばメーカーがテイラーのギターを出力するようにできます。
プログラムの詳しい説明
メーカ名と価格をコンストラクタに持つGuitarクラスを作成しています。
7行目で複数のGuitarインスタンスを持つlistリストを作成しています。
43行目では関数型インターフェースのPredicateを利用し、
testメソッドをGuitarクラスを引数リストで受け取れるようにオーバーライドしています。
33行目でprintメソッドを作成し、引数にGuitarクラスのリストをlist変数で受け取り、Predicateのインスタンスをguitar変数で受け取れるようにしています。
Predicateの戻り値はbooleanなので、ifの条件式にtestメソッド、testメソッドの引数に
変数listのリストを拡張for文で回した変数gを指定しています。
13行目で価格が200000円以上を出力するための匿名クラス、
19行目でメーカーがテイラーのギターを出力するための匿名クラスを作成しています。
26行目で、printメソッドにギターの一覧情報が格納されているlistリスト、ギターの価格を条件式に持つ匿名クラスを渡しています。
28行目で、printメソッドにギターの一覧情報が格納されているlistリスト、ギターの名前を条件式に持つ匿名クラスを渡しています。
ラムダ式に置き換える
ラムダ式の構文
(引数)->式;
(引数)->{文;}
引数が一つであれば()は省略可能
サンプルプログラム
出力結果
===============200000円以上のギターを出力===============
[メーカー] : ギブソン [価格] : 200000円
[メーカー] : テイラー [価格] : 340000円
===============メーカーがテイラーのギターを出力===============
[メーカー] : テイラー [価格] : 340000円
===============引数にラムダ式を直接記載することも可能===============
[メーカー] : テイラー [価格] : 340000円
ラムダ式を書くための手順
- 利用したい関数型インターフェースをオーバーライドする
- 関数型インターフェースを引数にもつメソッドを定義する
- ラムダ式をメソッドの引数に渡す
という手順で記述します。
ラムダ式ではメソッドを1つだけもつインターフェースを使用するという前提があります。
そのため、Predicate関数型インターフェースはtestメソッドだけを持っているがわかっているため、メソッド名は省略できます。
testメソッドの引数や戻り値のデータ型もインターフェースをオーバーライドした際に定義されているため、省略できます。
簡単に言うと、
左には引数の名前、右側にはメソッドの処理を記述します。
関数型インターフェースを覚えることが重要
ラムダ式を利用するためにはまず、
関数型インターフェースを覚えることが重要です。
自分でインターフェースを作成して利用することも可能ですが、
関数型インターフェースを利用すれば大抵のことは解決できます。
関数型インターフェース
関数型インターフェースはすべて総称型です。
全てではないですが、主要な関数型インターフェースの一覧です。
- Predicate<T> boolean値を返す(testメソッド)
- Consumer<T> 受け取った引数を処理し、値を返さない(acceptメソッド)
- Supplier<T> 引数を受け取らず、何かの値を作成して返す(getメソッド)
- Function<T,R> 引数を他の型のに変換して返す(apply)
今回はif文の条件式で利用したいためboolean値を返すPredicateインターフェースを利用しました。
testメソッドを持っているため、testメソッドをオーバーライドします。
Functionインターフェースは、例えばGuitterクラスを引数で渡したけど戻り値はString型で受け取りたい場合など、
引数のデータ型と戻り値のデータ型が異なる場合に利用します。
applyメソッドを持っているため、applyメソッドをオーバーライドして利用します。