jdk1.8新特性:Lambda表示式
Lambda表示式
一、函數語言程式設計思想概述
在數學中,函式就是有輸入量、輸出量的一套計算方案,也就是“拿什麼東西做什麼事情”。相對而言,物件導向過分強調“必須通過物件的形式來做事情”,而函式式思想則儘量忽略物件導向的複雜語法——強調做什麼,而不是以什麼形式做。
二、傳統寫法程式碼示例
public class demo01 {
public static void main(String[] args) {
Runnable runnable = new Runnable(){
public void run(){
System.out.println("多執行緒任務執行");
}
};
new Thread(runnable).start();
}
}
說明:
- Thread類需要Runnable介面作為引數,其中的抽象run方法是用來指定執行緒任務內容的核心;
- 為了指定run的方法體,不得不需要Runnable介面的實現類;
- 為了省去定義一個RunnableImpl實現類的麻煩,不得不使用匿名內部類;
- 必須覆蓋重寫抽象run方法,所以方法名稱、方法引數、方法返回值不得不再寫一遍,且不能寫錯;
- 而實際上,似乎只有方法體才是關鍵所在
三、上述示例使用Lambda的寫法
public class demo01 {
public static void main(String[] args) {
new Thread(()->{
System.out.println("多執行緒啟動");
}).start();
}
}
上例中,核心程式碼其實只是如下所示的內容:() -> System.out.println("多執行緒任務執行!")
四、Lambda標準格式
Lambda省去物件導向的條條框框,格式由3個部分組成:
- 一些引數
- 一個箭頭
- 一段程式碼
Lambda表示式的標準格式為:(引數型別 引數名稱) -> { 程式碼語句 }
格式說明:
- 小括號內的語法與傳統方法引數列表一致:無引數則留空;多個引數則用逗號分隔。
- ->是新引入的語法格式,代表指向動作。
- 大括號內的語法與傳統方法體要求基本一致
五、練習:使用Lambda標準格式(無參無返回)
給定一個廚子Cooker介面,內含唯一的抽象方法makeFood,且無引數、無返回值。如下:
public interface Cooker {
void makeFood();
}
在下面的程式碼中,請使用Lambda的標準格式呼叫invokeCook方法,列印輸出“吃飯啦!”字樣:
public class demo01 {
public static void main(String[] args) {
invokeCook(() -> {
System.out.println("吃飯啦!");
});
}
private static void invokeCook(Cooker c){
c.makeFood();
}
}
六、Lambda的引數和返回值
需求:使用Lambda表示式對存在陣列中的Person型別的物件資料按照年齡的降序輸出。
傳統寫法:
public class Demo02 {
public static void main(String[] args) {
// 本來年齡亂序的物件陣列
Person[] array = {
new Person("古力娜扎", 19),
new Person("迪麗熱巴", 18),
new Person("馬爾扎哈", 20) };
// 匿名內部類
Comparator<Person> comp = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o2.getAge() - o1.getAge();
}
};
Arrays.sort(array, comp); // 第二個引數為排序規則,即Comparator介面例項
for (Person person : array) {
System.out.println(person);
}
}
}
Lambda寫法:
public class demo02 {
public static void main(String[] args) {
// 本來年齡亂序的物件陣列
Person[] array = {
new Person("古力娜扎", 19),
new Person("迪麗熱巴", 18),
new Person("馬爾扎哈", 20) };
Arrays.sort(array,(Person p1,Person p2) -> {
return p2.getAge() - p1.getAge();
});
for (Person person : array) {
System.out.println(person);
}
}
}
七、練習
給定一個計算器Calculator介面,內含抽象方法calc可以將兩個int數字相加得到和值:
public interface Calculator {
int calc(int a, int b);
}
程式碼示例:使用Lambda的標準格式呼叫invokeCalc方法,完成120和130的相加計算
public class demo03 {
public static void main(String[] args) {
invokeCalc(120,130,(int a,int b) -> {
return a + b;
});
}
private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
System.out.println("結果是:" + result);
}
}
八、Lambda省略格式
Lambda強調的是“做什麼”而不是“怎麼做”,所以凡是可以根據上下文推導得知的資訊,都可以省略。例如上例還可以使用Lambda的省略寫法:
public static void main(String[] args) {
invokeCalc(120, 130, (a, b) -> a + b);
}
省略規則:
在Lambda標準格式的基礎上,使用省略寫法的規則為:
- 小括號內引數的型別可以省略;
- 如果小括號內有且僅有一個引數,則小括號可以省略;
- 如果大括號內有且僅有一個語句,則無論是否有返回值,都可以省略大括號、return關鍵字及語句分號。
注意:關於第三點如果省略一個,那麼必須同時都得省略。
九、練習:使用Lambda省略格式
仍然使用前文含有唯一makeFood抽象方法的廚子Cook介面,在下面的程式碼中,請使用Lambda的省略格式呼叫invokeCook方法,列印輸出“吃飯啦!”字樣:
public class demo01 {
public static void main(String[] args) {
invokeCook(() -> System.out.println("吃飯啦!")
);
}
private static void invokeCook(Cooker c){
c.makeFood();
}
}
十、Lambda的使用前提
Lambda的語法非常簡潔,完全沒有物件導向複雜的束縛。但是使用時有幾個問題需要特別注意:
- 使用Lambda必須具有介面,且要求介面中有且僅有一個抽象方法。
無論是JDK內建的Runnable、Comparator介面還是自定義的介面,只有當介面中的抽象方法存在且唯一時,才可以使用Lambda。 - 使用Lambda必須具有上下文推斷。
也就是方法的引數型別必須為Lambda對應的介面型別,才能使用Lambda作為該介面的例項。
舉例:
private static void invokeCook(Cooker cook) {
cook.makeFood();
}
對於invokeCook方法的引數型別必須是介面,這裡Cooker就是一個介面。
(備註:有且僅有一個抽象方法的介面,稱為“函式式介面”。)
相關文章
- JDK1.8新特性--Lambda表示式JDK
- JDK1.8新特性之Lambda表示式JDK
- JDK1.8新特性之Lambda表示式()->JDK
- jdk1.8 新特性之 lambda表示式JDK
- JDK1.8的新特性之Lambda表示式JDK
- jdk1.8 新特性之 如何寫lambda表示式JDK
- JDK1.8最新特性--Lambda表示式(重點)JDK
- JDK1.8新特性:Lambda表示式語法和內建函式式介面JDK函式
- [Java學習筆記]JDK1.8新特性學習(一)Lambda表示式Java筆記JDK
- JDK1.8之lambda表示式JDK
- JDK1.8 之Lambda表示式JDK
- Java 8新特性(一):Lambda表示式Java
- .NET3.5新特性,Lambda表示式
- JDK 1.8 新特性之Lambda表示式JDK
- Java8新特性(1):Lambda表示式Java
- Java8新特性(一)-Lambda表示式Java
- java8 新特性之Lambda 表示式Java
- JDK新特性-Lambda表示式的神操作JDK
- java-反射,介面新特性,Lambda表示式Java反射
- Java8 新特性之 Lambda 表示式Java
- C++11新特性之Lambda表示式C++
- .net framework3.5新特性:Lambda表示式Framework
- jdk1.8 lambda表示式入門JDK
- java8新特性之lambda表示式(一)Java
- JDK1.8及以上的Lambda表示式JDK
- JDK1.8 Lambda 表示式的學習JDK
- Java8新特性第1章(Lambda表示式)Java
- JDK1.8中Lambda表示式的應用JDK
- java8特性-lambda表示式Java
- Java8新特性——從Lambda表示式到Stream流Java
- Java 8新特性:lambda表示式(四)轉載總結Java
- 【原創】.net framework3.5新特性1:Lambda表示式Framework
- JDK1.8之Lambda解析與表示式的使用JDK
- java8的新特性之lambda表示式和方法引用Java
- JDK8+的lambda(λ)表示式特性JDK
- Java 8 流特性和 Lambda 表示式Java
- C#10新特性-lambda 表示式和方法組的改進C#
- C#特性-匿名方法和Lambda表示式C#