弱小和無知不是生存的障礙,傲慢才是。——《三體》
什么是Lambda表達式
Lambda表達式是表示可傳遞匿名函數的一種簡潔方式,Lambda表達式沒有名稱,但是有參數列表、函數主體、返回類型,還可能有一個可以拋出的異常列表。它是Java8新增的特性,有了它我們再也不用像之前那樣寫一堆笨重的匿名類代碼了,我們先來體驗一下。
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
與匿名函數對比
下面我們先舉個例子,有這樣一個表示口罩的類:
package one.more.study;
/**
* 口罩
*/
public class Mask {
/**
* 品牌
*/
private String brand;
/**
* 類型
*/
private String type;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
再創建一個口罩列表,添加一些口罩對象:
List<Mask> maskList = new ArrayList<>();
maskList.add(new Mask("3M", "KN95"));
maskList.add(new Mask("3M", "FFP2"));
maskList.add(new Mask("Honeywell", "KN95"));
maskList.add(new Mask("Honeywell", "N95"));
現在我們按照品牌給這個口罩列表進行排序。在Java8之前,我們可以用匿名函數進行實現:
maskList.sort(new Comparator<Mask>() {
@Override
public int compare(Mask o1, Mask o2) {
return o1.getBrand().compareTo(o2.getBrand());
}
});
我們再使用Lambda表達式實現一下:
maskList.sort((Mask o1, Mask o2) -> o1.getBrand().compareTo(o2.getBrand()));
顯而易見,使用Lambda表達式以后,代碼看起來更清晰更簡潔了。假如你還是一臉懵圈的話也沒關系,這里我只是想顯擺一下Lambda表達式很牛掰,接下來我會一點點地詳細講解清楚。
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
Lambda表達式的組成
Lambda表達式由三部分組成,以上面的口罩排序的例子為例,如下圖:
- 參數列表:本例中是兩個
Mask
對象的參數,采用的是Comparator接口中compare方法的參數。 - 箭頭:
->
把參數列表和主體分隔為兩個部分。 - 主體:本例中是把比較口罩品牌的表達式作為Lambda表達式的返回。主體可以修改成另外一種寫法,含義是一樣的:
maskList.sort((Mask o1, Mask o2) -> {
return o1.getBrand().compareTo(o2.getBrand());
});
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
Lambda表達式的基本語法
從上面的例子中的兩個種寫法中,可以看出Lambda表達式有兩種基本語法,分別如下:
- (參數列表)
->
表達式 - (參數列表)
->
{ 多條語句 }
只看這兩條干癟的語法,理解起來比較困難,實踐出真知,我們來多舉幾個例子。
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
Lambda表達式示例
- 我們提到的例子,Lambda表達式的參數列表有兩個Mask類型的參數,主體是比較兩個Mask對象的品牌,返回的是一個int類型。當主體是一個表達式時,不需要return語句,隱含return該表達式的返回值。
(Mask o1, Mask o2) -> o1.getBrand().compareTo(o2.getBrand())
- 參數列表中僅有一個Mask類型的參數,返回的是一個String類型,是該Mask對象的品牌信息。
(Mask mask) -> mask.getBrand()
- 參數列表中僅有一個Mask類型的參數,返回的是一個boolean類型,是該Mask對象的類型是否為N95。
(Mask mask) -> mask.getType() == "N95"
- 參數列表中沒有任何參數,返回的是一個int類型。
() -> 996
- 參數列表中有兩個int類型的參數,但是沒有返回值(void)。在主體中可以寫多條語句,不過記住要用
{
和}
將其包裹。
(int x, int y) -> {
System.out.println("萬貓學社想對你說:");
System.out.println("第一個參數是:" + x);
System.out.println("第二個參數是:" + y);
System.out.println("兩數之和是:" + (x + y));
}
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
小測試
看了這么多的例子,是不是擼胳膊挽袖子准備大干一場?別急,檢驗出真知,我們先簡單測試一下。以下的Lambda表達式有哪幾個是正確的?
() -> {}
() -> "萬貓學社"
() -> { "萬貓學社" }
() -> { return "萬貓學社"; }
() -> return "萬貓學社";
請思考片刻…
.
.
.
.
.
.
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
宣布答案:第1、2和4個是正確的,第3和5個是錯誤的。我們來逐個分析一下:
() -> {}
:正確,這個Lambda表達式沒有參數,也沒有任何返回。() -> "萬貓學社"
:正確,這個Lambda表達式沒有參數,主體是一個表達式,返回String類型。() -> { "萬貓學社" }
:錯誤,"萬貓學社"
是一個表達式,不是一個語句,不能使用{
和}
將其包裹,可以修改為() -> "萬貓學社"
。() -> { return "萬貓學社"; }
:正確,這個Lambda表達式沒有參數,主體是一個語句,使用{
和}
將其包裹,返回String類型。() -> return "萬貓學社";
:錯誤,return "萬貓學社";
是一個語句,不是一個表達式,必須使用{
和}
將其包裹,可以修改為() -> { return "萬貓學社"; }
。
如果你全部答對,恭喜你,你已經基本掌握Lambda表達式的基本語法;如果你有答錯的,沒關系,重新再看一遍,再復習鞏固一下。
學習的路上,我與你一起前行。
《死磕Lambda表達式》系列
- 死磕Lambda表達式(一):初識Lambda
- 死磕Lambda表達式(二):Lambda的使用
- 死磕Lambda表達式(三):更簡潔的Lambda
- 死磕Lambda表達式(四):常用的函數式接口
- 死磕Lambda表達式(五):Comparator復合
- 死磕Lambda表達式(六):Consumer、Predicate、Function復合
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。