死磕Lambda表示式(一):初識Lambda
弱小和無知不是生存的障礙,傲慢才是。——《三體》
什麼是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表示式的基本語法;如果你有答錯的,沒關係,重新再看一遍,再複習鞏固一下。
學習的路上,我與你一起前行。
歡迎關注微信公眾號:萬貓學社,每週一分享Java技術乾貨