Java8之Lambda表達式使用解讀
一、初識Lambda
Lambda 表達式(lambda expression)是一個匿名函數(shù),Lambda表達式基于數(shù)學中的λ演算得名,直接對應(yīng)于其中的lambda抽象(lambda abstraction),是一個匿名函數(shù),即沒有函數(shù)名的函數(shù)。
Lambda表達式可以表示閉包(注意和數(shù)學傳統(tǒng)意義上的不同)。
這是來自萬能的百度百科對于lambda表達式的解釋,懂的都懂,不懂的真是聽君一席話,如聽一席話。
Lambda表達式在Java8中及后續(xù)版本占據(jù)了舉足輕重的地位,對于函數(shù)式編程來說是必不可少的一環(huán),所以學會lambda表達式,對于使用Java8的同學是必經(jīng)之路
舉個栗子,Java8中的stream你們不會沒有用過吧?什么?你還在用Java7?阿巴阿巴阿巴…好吧,那我直接用代碼舉個栗子吧。
1.Lambda栗子
需求是這樣的,二哥第一次來到了大城市,到了大城市就去了 大 保 健,這個時候肯定就要選女朋友了,根據(jù)姓名、大小、價位等,咳咳咳…說錯了,是根據(jù)姓名、鞋碼、身價來選擇,二哥要求經(jīng)理讓這些女朋友按照身價來正序排隊站好。
@Data
@AllArgsConstructor
public class Girl {
private String name;
private Double size;
private Double price;
} public static void main(String[] args) {
ArrayList<Girl> list = Lists.newArrayList();
list.add(new Girl("露西",33d,2000d));
list.add(new Girl("格蕾絲",36d,3000d));
list.add(new Girl("安娜",28d,1500d));
list.add(new Girl("克瑞斯",31d,1800d));
//匿名函數(shù)類實現(xiàn)
list.sort(new Comparator<Girl>() {
@Override
public int compare(Girl o1, Girl o2) {
return o1.getPrice().compareTo(o2.getPrice());
}
});
list.stream().forEach(System.out::println);
Collections.shuffle(list);
System.out.println("-------------我是分隔符-----------------");
//lambda實現(xiàn)
list.sort((Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice()));
list.stream().forEach(System.out::println);
}
不難看出,兩種方式都實現(xiàn)了讓女朋友們按照身價排隊。那么我們著重來看看Lambda表達式。

2.Lambda表達式的組成
(Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice());
- 參數(shù)列表:本例中是兩個Mask對象的參數(shù),采用的是Comparator接口中compare方法的參數(shù)。
- 箭頭:->把參數(shù)列表和主體分隔為兩個部分。
- 主體:本例中是把比較價格的表達式作為Lambda表達式的返回。主體可以修改成另外一種寫法,含義是一樣的:
list.sort((Girl g1, Girl g2)-> {
return g1.getPrice().compareTo(g2.getPrice());
});由此可以看出,lambda表達式語法格式可以分為兩種:
- 1.(parameters) -> expression //參數(shù)列表加單條表達式
- 2.(parameters) ->{ statements; } //參數(shù)列表加花括號和多條語句
以下是lambda表達式的重要特征:
- 可選類型聲明:不需要聲明參數(shù)類型,編譯器可以統(tǒng)一識別參數(shù)值。
- 可選的參數(shù)圓括號:一個參數(shù)無需定義圓括號,但多個參數(shù)需要定義圓括號。
- 可選的大括號:如果主體包含了一個語句,就不需要使用大括號。
- 可選的返回關(guān)鍵字:如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定表達式返回了一個數(shù)值。
3.舉個栗子
// 1. 不需要參數(shù),返回值為 5
() -> 5
// 2. 接收一個參數(shù)(數(shù)字類型),返回其2倍的值
x -> 2 * x
// 3. 接受2個參數(shù)(數(shù)字),并返回他們的差值
(x, y) -> x – y
// 4. 接收2個int型整數(shù),返回他們的和
(int x, int y) -> x + y
// 5. 接受一個 string 對象,并在控制臺打印,不返回任何值(看起來像是返回void)
(String s) -> System.out.print(s)
// 6.接受兩個int參數(shù),多條語句進行比較返回1或者0
(int s1, int s2)->{
if(s1>s2){
return 0;
}
return 1;
}二、Lambda更進一步
1.類型推斷
//lambda實現(xiàn)
list.sort((Girl g1, Girl g2)-> g1.getPrice().compareTo(g2.getPrice()));
//lambda簡化寫法
list.sort((g1, g2)-> g1.getPrice().compareTo(g2.getPrice()));2.方法引用
方法引用通過方法的名字來指向一個方法。方法引用可以使語言的構(gòu)造更緊湊簡潔,減少冗余代碼。方法引用使用一對冒號 :: 。
Comparator<Girl> comparator = (g1, g2)-> g1.getPrice().compareTo(g2.getPrice()); //方法引用 Comparator.comparing(Girl::getPrice);
當你需要方法引用時,目標引用放在分隔符::前,方法的名稱放在分隔符::后。
比如,上面的Girl::getPrice,就是引用了Mask中定義的getPrice方法。
方法名稱后不需要加括號,因為我們并沒有實際調(diào)用它。
方法引用提高了代碼的可讀性,也使邏輯更加清晰,在一些stream流中,相信大家也經(jīng)常會用到。
例如:
List<String> collect = list.stream().map(Girl::getName).collect(Collectors.toList()); list.stream().forEach(System.out::println);
我們看到第一行通過Girl::getName方法引用,我們收集到了所有女孩的名字,那么第二行我們通過System.out::println打印出了list中的所有對象。
舉個栗子:
我們先改造一下實體類,增加了空參構(gòu)造函數(shù),增加了幾個方法,有靜態(tài)方法和非靜態(tài)方法。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Girl {
private String name;
private Double size;
private Double price;
//Supplier是jdk1.8的接口,這里和lamda一起使用了
public static Girl create(final Supplier<Girl> supplier) {
return supplier.get();
}
public static void makeUp(final Girl girl) {
System.out.println("化妝 " + girl.toString());
}
public void follow(final Girl another) {
System.out.println("Following the " + another.toString());
}
public void dressUp() {
System.out.println("更衣 " + this.toString());
}
}
4種不同的方法引用
//構(gòu)造器引用:它的語法是Class::new,或者更一般的Class< T >::new實例如下:
Girl girl = Girl.create(Girl::new);
List<Girl> girls = Arrays.asList(girl);
//靜態(tài)方法引用:它的語法是Class::static_method,實例如下:
girls.forEach(Girl::makeUp);
//特定類的任意對象的方法引用:它的語法是Class::method實例如下:
girls.forEach(Girl::dressUp);
//特定對象的方法引用:它的語法是instance::method實例如下:
girls.forEach(girl::follow);到這里,大家對lambda表達式應(yīng)該有了初步的認識,可以在平時編碼中多使用,畢竟實踐出真知!!
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于Java SSM框架實現(xiàn)簡易的評教系統(tǒng)
這篇文章主要介紹了通過Java SSM框架實現(xiàn)一個簡易的評教系統(tǒng)的示例代碼,文中的代碼講解詳細,感興趣的小伙伴可以了解一下2022-02-02
BeanUtils.copyProperties()參數(shù)的賦值順序說明
這篇文章主要介紹了BeanUtils.copyProperties()參數(shù)的賦值順序說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
關(guān)于maven項目引入maven庫沒有的jar處理辦法
這篇文章主要介紹了關(guān)于maven項目引入maven庫沒有的jar處理辦法,在平時開發(fā)中,有些jar包是不存在maven中央庫中的,那么此時該如何解決才能方便后續(xù)處理呢,需要的朋友可以參考下本文2023-03-03

