Java筆記:Lambda表示式

山上下了雪-bky發表於2024-03-03

Lambda表示式在Java中是函數語言程式設計的一種體現,允許把函式作為一個方法的引數傳遞進方法中,或者將函式作為方法的返回值。

1. 語法和基礎使用

語法:

// Lambda實現是一個簡單的表示式
(parameters) -> expression;
// Lambda實現是一個函式體
(parameters) -> {statements;}
  • parameters是引數列表,如果沒有引數,則需要使用一個空括號 () -> ...
  • 如果只有一個引數,則可以不用括號 parameter -> ... (推薦),也可以使用括號 (parameter) -> ...
  • 如果有多個引數,則正常使用引數列表即可 (parameter1, parameter2, ...) -> ...
  • 由於java中對於Lambda表示式的型別推斷機制,其中的parameter可以宣告引數型別,也可以不用,如 (int parameter) -> ...

示例1:只有一個引數,函式主體是簡單表示式。

List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu");
// 單引數 + 簡單表示式,也是將Lambda表示式作為函式傳遞給方法
names.forEach(name -> System.out.println(name));

示例2:使用Lambda表示式實現函式式介面,並作為引數傳入方法。

public class Main {
    public static void main(String[] args) {
        // 使用Lambda表示式實現介面
        AddOperation addOperation = (a, b) -> System.out.println(a + b);
        // 執行對應的介面方法
        addOperation.operate(1, 2);
        // 將Lambda表示式作為引數傳入方法
        Main.add_operate(3, 4, addOperation);
    }

    /**
     * 定義一個介面
     */
    interface AddOperation {
        void operate(int a, int b);
    }

    /**
     * 將介面作為引數型別
     */
    public static void add_operate(int a, int b, AddOperation addOperation) {
        addOperation.operate(a, b);
    }
}

函式式介面: 能用Lambda表示式實現的介面必須是函式式介面,即內部只有一個抽象方法的介面。可以使用註解@FunctionalInterface來標識該介面,如果該介面不滿足函式式介面的定義則會報錯,例如介面中有兩個抽象方法。

2. 變數作用域

Lambda表示式中使用的區域性變數,是隱式的final型別,即不可以在表示式後再修改該變數的值。以下示例會報編譯錯誤:

public class Main {
    public static void main(String[] args) {
        int b = 1;
        // b為隱式的final型別,不允許在Lambda後面再修改b的值
        // 此處IDE會提示:variable used in lambda expression should be final or effectively final
        AddOperation addOperation = a -> System.out.println(a + b);
        b = 3;
        addOperation.operate(2);
    }

    /**
     * 定義一個介面
     */
    interface AddOperation {
        void operate(int a);
    }
}

Lambda表示式中的引數定義也不能和區域性變數的引數名稱同名,以下示例會報編譯錯誤:

public class Main {
    public static void main(String[] args) {
        int b = 1;
        int c = 2;
        // 此處Lambda表示的引數b和區域性變數的名稱相同,編譯會報錯
        // IDE也會提示:Variable 'b' is already defined in the scope
        AddOperation addOperation = b -> System.out.println(b + c);
        addOperation.operate(2);
    }

    /**
     * 定義一個介面
     */
    interface AddOperation {
        void operate(int a);
    }
}

相關文章