関数型インターフェースとラムダ式
Javaマスターへの第一歩!プログラミングの基本を学びましょう!
変数とデータ型2024/2/23 6:112024/11/25 1:06演算子2024/2/23 6:102024/11/25 1:06制御文2024/2/23 6:092024/11/25 1:06配列2024/2/23 6:082024/11/25 1:06メソッド2024/2/23 6:062024/11/25 1:06オブジェクト指向2024/2/23 6:052024/11/25 1:06コンストラクタ2024/2/23 6:032024/11/25 1:06カプセル化2024/2/23 6:022024/11/25 1:06継承2024/2/23 6:002024/11/25 1:06ポリモーフィズム2024/2/23 5:502024/11/25 1:06パッケージとクラスライブラリ2024/2/23 5:472024/11/25 1:06抽象クラスとインターフェース2024/2/23 5:432024/11/25 1:06コレクションフレームワーク2024/2/23 5:442024/11/25 1:06関数型インターフェースとラムダ式2024/2/23 5:412024/11/25 1:06Stream API2024/2/23 5:332024/11/25 1:06例外処理2024/7/21 23:092024/11/25 1:06
このチャプターの目次
関数型インターフェースとは、抽象メソッドを1つしか持たないインターフェースのことです。ただし、defaultメソッドやstaticメソッドは持っていても構いません。
RunnableというJavaのクラスライブラリに元々あるインターフェースを見てみましょう。run(実行する)という抽象メソッドがあります。
抽象メソッドは1つだけなので、FunctionalInterfaceアノテーションを宣言の前(1行目)に指定しています。
アノテーションは注釈という意味です。抽象メソッドが1つだけなら関数型インターフェースになるのですが、FunctionalInterfaceアノテーションで明示的に宣言するのが良いでしょう。
関数型インターフェースの実装
Runnableインターフェースを、まずは普通に実装していきます。implementsキーワードを使います。
クラス名はとしてみました。メソッドをオーバーライドしています。
このメソッドはOverrideだよと明言しているのがOverrideアノテーションです。引数の数の指定やデータ型の記述ミスで、予期せぬオーバーライドやオーバーライド失敗を防ぐための注釈です。なくても良いのですが、書いておいた方が安全です。
処理の中では、Exampleを実行しましたメッセージをprintlnしています。
Exapmleクラスを実行する側のmainメソッドについて、見ていきたいと思います。
Exampleクラスをnewして、Runnableインターフェース型の変数eに代入しています。として実行しています。
Runnableインターフェースはマルチスレッドのプログラムを作るためのものなので、本来このようなやり方はしないのですが、伝わりやすくしようと、今回採用しています。
実際に実行すると、コマンドラインに「Exampleを実行しました。」メッセージが出力されるわけです。
でも、これをやりたいだけなのに、Runnableインターフェースも含めると3つのファイルを使っているのです。
- Runableインターフェース
- Runableインターフェースを実装するクラス
- mainメソッドを持つクラス
この中の、Runnableインターフェースを実装しているExampleクラスって、本当に必要なのでしょうか?ということで、次のような記述ができるようになっているのです。
内部クラスにする
Exampleクラスを、mainメソッドを持つクラスの中に宣言します。クラスの中に記述されているクラスを内部クラスと呼びます。
こうすると、mainメソッドの中からExampleクラスを呼び出すことができます。mainメソッドの中は先ほどと同じです。
匿名クラスにする
一時的な使い捨てのクラスとしての用途です。
classの宣言も、クラス名もありません。Runnableインターフェースをnewしています。実際にはインターフェースをnewしているのではなく、匿名クラスをnewしているのがポイントです。
内部クラスの時よりも、書式が簡潔になりました。privateなスタティックclassを作る必要もありません。
これを匿名クラスと呼びます。
ラムダ式とは?
ラムダ式とは、「匿名クラスの表記を省略したもの」です。コードを簡潔に記述するための言語仕様で、ラムダ式を使うことでメソッドを簡単に定義し、その場で使用することができます。それでは、どのように省略していくのか、みていきましょう。
ラムダ式に変換する10の手順
- インターフェースの表記を省略
- 修飾子の表記を省略
- 抽象メソッドの戻り値の型を省略
- 抽象メソッドの名前を省略
- 抽象メソッドの引数の型を省略
- returnを省略
- 抽象メソッドのとを省略
- 匿名クラスのを省略
- 演算子を省略
- アロー演算子を記述
最後だけ記述です。
いっぱいありすぎて混乱するかもしれませんが、この10の手順に従えば、匿名クラスの宣言がラムダ式になります。
省略前のソースコードは以下のようになります。
- インターフェースの表記を省略する。
new演算子のところのを削除しました。
- 修飾子の表記を省略する。
runメソッドのを削除しました。
- 抽象メソッドの戻り値の型を省略する。
を削除しました。
- 抽象メソッドの名前を省略する。
を削除しました。
- 抽象メソッドの引数の型を省略します。
このサンプルの場合、runメソッドには引数がないので、省略できるものがありません。引数がある場合は、型を削除してください。
- returnを省略します。
戻り値もないので省略できるものがありません。return文がある場合は、消去してください。
- 抽象メソッドの{ }と;を省略します。
との命令文だけが1行残りました。
- 匿名クラスの{ }を省略します。
セミコロンだけが残りました。
- new演算子を省略します。
- 最後にアロー演算子を記述します。
の後ろに記述します。
まとめるとこうなります。
ラムダ式の部分は
ココです。
とっても簡潔な記述になりました。作成したクラスもこのクラスのみです。
ラムダ式は、Stream APIと呼ばれる言語仕様でよく利用されます。