Lambda相當於就是一個匿名方法,其在代替匿名內部類創建對象的時候,Lambda表達式代碼塊會代替實現抽象方法的方法體
Lambda表達式的目標類型必須是“函數式接口(FunctionalInterface)”。函數式接口只能包含一個抽象方法接口。函數式接口可以包含多個默認方法、類方法、但只能一個抽象方法
函數式接口
- 有且只有一個沒有default關鍵字修飾的接口
可以多個default關鍵字的抽象方法、類方法、變量
語法組成元素
- 形參列表。形參可以省略數據類型。若只有一個參數,可以將圓括號省略
- 箭頭(->)
- 代碼塊。如果只有一條語句,Lambda表達式可以省略花括號。代碼塊只能有一條return語句,並且可以省略return關鍵字
public class Lam {
@FunctionalInterface
interface Try{
Integer ss();
}
public static void main(String[] args) {
Try i=()->"sa".indexOf("a");
System.out.println(i.ss());
}
}
Lambda的代碼塊中就是用來實現接口的抽象方法,而且有且只能有一個。若有default關鍵字的抽象方法是不屬於函數式接口(FunctionalInterface)
存在@FunctionalInterface註解的一定是函數式接口,沒有@FunctionalInterface不一定就不是函數式接口
public class Lam {
@FunctionalInterface
interface Try {
String s = "1";
Integer ss();
default Integer bb() {
return 0;
}
}
public static void main(String[] args) {
Try i = () -> "sa".indexOf("a");
System.out.println(i.s);
System.out.println(i.ss());
}
}
方法引用與構造器引用
種類 | 示例 | 說明 | 對應的Lambda表達式 |
---|---|---|---|
引用類方法 | 類名::類方法 | 函數式接口中實現的方法的全部參數都傳遞給類方法作爲參數 | (a,b,…)->類名.類方法(a,b,…) |
特定對象的實例方法 | 對象::實例方法 | 函數式接口中實現的方法的全部參數都傳遞給類方法作爲參數 | (a,b,…)->對象.實例方法(a,b,…) |
引用某類對象的實例方法 | 類名::實例方法 | 函數式接口中實現的方法第一個參數作爲調用者,之後的參數都作爲方法的參數 | (a,b,…)->a.實例方法(b,…) |
引用構造方法 | 類名::new | 函數式接口中實現的方法的全部參數都傳遞給類方法作爲參數 | (a,b,…)->類名.new(a,b,…) |
使用::這種方式,抽象方法肯定是存在參數的
其實上面三類可以歸爲一類來看待,這是形式不同而已
public class Lam {
@FunctionalInterface
interface Try {
String s = "1";
Integer ss(String s);
default Integer sb() {
return 0;
}
}
public static void main(String[] args) {
Try i = "sa"::indexOf;
System.out.println(i.s);
System.out.println(i.ss("a"));
}
引用構造方法
public class Lam {
@FunctionalInterface
interface Try {
String s = "1";
String ss(String s);
default Integer sb() {
return 0;
}
}
public static void main(String[] args) {
Try i = String::new;
System.out.println(i.s);
System.out.println(i.ss("a"));
}
等價於
public class Lam {
@FunctionalInterface
interface Try {
String s = "1";
String ss(String s);
default Integer sb() {
return 0;
}
}
public static void main(String[] args) {
Try i = new Try(){
@Override
public String ss(String s) {
return new String(s);
}
};
System.out.println(i.s);
System.out.println(i.ss("a"));
}
Lambda表達式與匿名函數的異同點
同
- Lambda表達式與匿名內部類一樣,都可以直接訪問“effectivly final”的局部變量,以及外部類的成員變量(包括實例變量和類變量)
- Lambda表達式創建的對象與匿名內部類生成的對象一樣,都可以直接調用從接口中繼承的默認方法
異
- 匿名內部類可以爲任意接口創建實例——不管接口包含多少抽象方法,只要匿名內部類實現所有的抽象方法即可;但Lambda表達式只能爲函數式接口創建實例
- 匿名內部類可以爲抽象類甚至普通類創建實例;但Lambda表達式只能爲函數式接口創建實例
- 匿名內部類實現的抽象方法的方法體運行調用接口中定義的默認方法;但Lambda表達式的代碼塊不允許調用接口中定義的默認方法
更多內容可以關注微信公衆號,或者訪問AppZone網站