関数型インターフェースを使う際にいちいち関数を別の場所に用意するのが面倒な時があります。
一方「ラムダ式」を使えば処理内容を関数型インターフェースに直接代入できるので便利です。
ここではソースコードを見ながらラムダ式の具体的な使い方を説明します。
ラムダ式を考える前に、まず「ラムダ式を使わない」サンプルをソース1に示します。
import java.lang.Runnable;
import java.util.function.Function;
public class Main{
public static void myrunnable1(){
System.out.println("hoge");
}
public static void myrunnable2(){
System.out.println("fuga");
}
public static String myfunction1( Integer a ){
return "piyo="+a;
}
public static String myfunction2( Integer a ){
return "foo="+a;
}
public static void main(String[] args) {
Runnable runnable;
Function< Integer, String > function;
runnable = Main::myrunnable1;
function = Main::myfunction1;
runnable.run();
System.out.println( function.apply( 123 ) );
// 関数オブジェクトを再代入する
runnable = Main::myrunnable2;
function = Main::myfunction2;
runnable.run();
System.out.println( function.apply( 456 ) );
}
}
hoge piyo=123 fuga foo=456
ではこのサンプルを「ラムダ式を使った」サンプルに修正してみましょう。
まずJavaのラムダ式の基本的な書式は次のようになります。
Java 以外のプログラミング言語でも似たような書き方をするので覚えておいて下さい。
(引数) -> {処理内容};
なお引数の型やラムダ式の戻り値の型を指定する必要はありません。
この機能を「型推論」と呼びます。
このラムダ式を使ってソース1を書き直すと、次のソース2の様になります。
import java.lang.Runnable;
import java.util.function.Function;
public class Main{
public static void main(String[] args) {
Runnable runnable;
Function< Integer, String > function;
// ラムダ式を関数型インターフェースに代入
runnable = () -> { System.out.println("hoge"); };
function = (a) -> { return "piyo="+a; };
runnable.run();
System.out.println( function.apply( 123 ) );
// ラムダ式を切り替える
runnable = () -> { System.out.println("fuga"); };
function = (a) -> { return "foo="+a; };
runnable.run();
System.out.println( function.apply( 456 ) );
}
}
実行結果は同じなので省略します。
ソース1とソース2を見比べると、ラムダ式を使った方がコード量が減るのでスッキリしています。
さらに、引数が1つだけの場合は ()も省略できます(引数が無い場合や2つ以上の場合は省略不可)。
また、処理内容が 1 行だけの場合は中括弧や return を省略することが可能です。
例えばソース 2 のラムダ式を省略して書いたのが次のソース3です。
import java.lang.Runnable;
import java.util.function.Function;
public class Main{
public static void main(String[] args) {
Runnable runnable;
Function< Integer, String > function;
// ラムダ式を関数型インターフェースに代入
runnable = () -> System.out.println("hoge"); // 中括弧を省略
function = a -> "piyo="+a; // ()と中括弧と return を省略
runnable.run();
System.out.println( function.apply( 123 ) );
// ラムダ式を切り替える
runnable = () -> System.out.println("fuga"); // 中括弧を省略
function = a -> "foo="+a; // ()と中括弧と return を省略
runnable.run();
System.out.println( function.apply( 456 ) );
}
}
実行結果は同じなので省略します。
ソース2とソース3を見比べると更にスッキリしたことが分かります。
なお Java の場合は
ラムダ式の内部でローカル変数を使うとコンパイルエラーが出る
ので気をつけて下さい(ソース 4参考)。
※ フィールドにはアクセス可能
※ final が付いていればローカル変数も参照可能
import java.lang.Runnable;
public class Main{
public static void main(String[] args) {
int a = 0;
Runnable runnable;
runnable = () -> a = 1; // コンパイルエラー
}
}