1.21 Lambda表达式
Lambda 表達式(Lambda expression)是一個匿名函數,基于數學中的λ演算得名,也可稱為閉包(Closure)。
Lambda 表達式是推動 Java 8 發布的重要新特性,它允許把函數作為一個方法的參數(函數作為參數傳遞進方法中),下面通過例 1 來理解 Lambda 表達式的概念。
例 1
先定義一個計算數值的接口,代碼如下。
Calculable 接口只有一個方法 calculateInt,參數是兩個 int 類型,返回值也是 int 類型。實現方法代碼如下:
public class Test{/*** 通過操作符,進行計算** @param opr 操作符* @return 實現Calculable接口對象*/public static Calculable calculate(char opr) {Calculable result;if (opr == '+') {// 匿名內部類實現Calculable接口13 result = new Calculable() {// 實現加法運算@Override16 public int calculateInt(int a, int b) {return a + b;}};} else {// 匿名內部類實現Calculable接口23 result = new Calculable() {// 實現減法運算@Override26 public int calculateInt(int a, int b) {return a - b;}};}return result;} }方法 calculate 中 opr 參數是運算符,返回值是實現 Calculable 接口對象。代碼第 13 行和第 23 行都采用匿名內部類實現 Calculable 接口。代碼第 16 行實現加法運算。代碼第 26 行實現減法運算。
public static void main(String[] args) {int n1 = 10;int n2 = 5;// 實現加法計算Calculable對象 5 Calculable f1 = calculate('+');// 實現減法計算Calculable對象 7 Calculable f2 = calculate('-');// 調用calculateInt方法進行加法計算 9 System.out.println(n1 + "+" + n2 + "=" + f1.calculateInt(n1, n2));// System.out.printf("%d + %d = %d \n", n1, n2, f1.calculateInt(n1, n2));// 調用calculateInt方法進行減法計算 12 System.out.println(n1 + "-" + n2 + "=" + f1.calculateInt(n1, n2));// System.out.printf("%d - %d = %d \n", n1, n2, f2.calculateInt(n1, n2)); }代碼第 5 行中 f1 是實現加法計算 Calculable 對象,代碼第 7 行中 f2 是實現減法計算 Calculable 對象。代碼第 9 行和第 12 行才進行方法調用。
上述代碼中列出了兩種輸出方式,下面簡單介紹一下 Java 中常見的輸出函數:
輸出結果如下:
10+5=15 10-5=15例 1 使用匿名內部類的方法 calculate 代碼很臃腫,Java 8 采用 Lambda 表達式可以替代匿名內部類。修改之后的通用方法 calculate 代碼如下:
/** * 通過操作符,進行計算 * @param opr 操作符 * @return 實現Calculable接口對象 */ public static Calculable calculate(char opr) {Calculable result;if (opr == '+') {// Lambda表達式實現Calculable接口 10 result = (int a, int b) -> {return a + b;};} else {// Lambda表達式實現Calculable接口 15 result = (int a, int b) -> {return a - b;};}return result; }代碼第 10 行和第 15 行用 Lambda 表達式替代匿名內部類,可見代碼變得簡潔。通過以上示例我們發現,Lambda 表達式是一個匿名函數(方法)代碼塊,可以作為表達式、方法參數和方法返回值。
Lambda 表達式標準語法形式如下:
(參數列表) -> {// Lambda表達式體 }->被稱為箭頭操作符或 Lambda 操作符,箭頭操作符將 Lambda 表達式拆分成兩部分:
- 左側:Lambda 表達式的參數列表。
- 右側:Lambda 表達式中所需執行的功能,用{ }包起來,即 Lambda 體。
Java Lambda 表達式的優缺點
優點:
代碼簡潔,開發迅速
方便函數式編程
非常容易進行并行計算
Java 引入 Lambda,改善了集合操作(引入 Stream API)
缺點:
代碼可讀性變差
在非并行計算中,很多計算未必有傳統的 for 性能要高
不容易進行調試
函數式接口
Lambda 表達式實現的接口不是普通的接口,而是函數式接口。如果一個接口中,有且只有一個抽象的方法(Object 類中的方法不包括在內),那這個接口就可以被看做是函數式接口。這種接口只能有一個方法。如果接口中聲明多個抽象方法,那么 Lambda 表達式會發生編譯錯誤:
The target type of this expression must be a functional interface這說明該接口不是函數式接口,為了防止在函數式接口中聲明多個抽象方法,Java 8 提供了一個聲明函數式接口注解 @FunctionalInterface,示例代碼如下。
// 可計算接口 @FunctionalInterface public interface Calculable {// 計算兩個int數值int calculateInt(int a, int b); }在接口之前使用 @FunctionalInterface 注解修飾,那么試圖增加一個抽象方法時會發生編譯錯誤。但可以添加默認方法和靜態方法。
@FunctionalInterface 注解與 @Override 注解的作用類似。Java 8 中專門為函數式接口引入了一個新的注解 @FunctionalInterface。該注解可用于一個接口的定義上,一旦使用該注解來定義接口,編譯器將會強制檢查該接口是否確實有且僅有一個抽象方法,否則將會報錯。需要注意的是,即使不使用該注解,只要滿足函數式接口的定義,這仍然是一個函數式接口,使用起來都一樣。
提示:Lambda 表達式是一個匿名方法代碼,Java 中的方法必須聲明在類或接口中,那么 Lambda 表達式所實現的匿名方法是在函數式接口中聲明的。
總結
以上是生活随笔為你收集整理的1.21 Lambda表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.20 Java8新特性:Effect
- 下一篇: 1.22 Lambda表达式的3种简写方