学習雑記 JAVA21

ラムダ式と関数型インターフェース

ラムダ式 : メソッド定義を式として扱える機能で、主に関数型インターフェースを実装する時に使う。下記構文のように引数と処理式をアロー演算子( -> )で結ぶ

構文 Interface名 Object名 = (argument1, argument2, ...) -> {return Processing};

@ 引数の型はコンパイラが判断するので、記述する必要はない。(記述しても良い)

@ 引数を持たないメソッドでも使える()->{return Process};

@ 引数が1つだけの時、()を省略可能

@ 実行したい処理式が1つだけの時、{}を省略可能

{}を省略している時、戻り値がある場合、returnを省略する

@ 処理内容で変数を参照する場合は注意が必要

 

ラムダ式内にある変数のアクセスとスコープ

ラムダ式の変数スコープはそれを囲むブロックと同じ変数スコープを持つことになる。変数が重複するとコンパイルエラーになる。そのため、ラムダ式内でメソッドのローカル変数にアクセスできない。ただし、finalと修飾子がついている変数は利用できる。修飾されていなくとも実質的に変更がない場合でも許容はされる。

1. ラムダ式内で定義した変数を使うことはできる

Algorithm algorithm = (name) -> {
int x = 5;
while(x>0) {
System.out.println("Hello, " + name);
x--;
}
};

2. 外で定義した変数をラムダ式内で使う場合はコンパイルエラー

int x = 5; //外で定義した変数をラムダ式内で使用するとコンパイルエラー
Algorithm algorithm = (name) -> {
while(x>0) {
System.out.println("Hello, " + name);
x--;
}
};

3. ラムダ式内で使う変数を外で使用した場合もコンパイルエラー

Algorithm algorithm = (name) -> {
int x = 5;
while(x>0) {
System.out.println("Hello, " + name);
x--;
}
};
int y = x + 5; // x をラムダ式の外で使うとコンパイルエラー

 

付け替え可能なアルゴリズムを実現するGoFのStrategy(下記)

共通の方で使えるインターフェースを用意し、アルゴリズムを処理の流れを担当するクラスと、具体的なアルゴリズムを担当するクラスに分けて作成する。この時ラムダ式を使えば、実装が必要なメソッドをを1つだけ持つインターフェース型変数に実行したいこコードを代入することができるようになる。(このようなインターフェースを関数型インターフェースとよぶ)

interface Algorithm {
void abstractMethod(String name);
}
class Service {
private Algorithm logic;
public void setLogic(Algorithm logic) {
this.logic = logic;
}
public void doProcess(String name) {
this.logic.abstractMethod(name);
}
}
public class Main {
public static void main(String[] args) {
Algorithm algorithm = (name) -> {
System.out.println("Hello, " + name);
};
Service s = new Service();
s.setLogic(algorithm);
s.doProcess("LAMBDA");
}
}