死磕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表達式由三部分組成,以上面的口罩排序的例子為例,如下圖:

  1. 參數列表:本例中是兩個Mask對象的參數,采用的是Comparator接口中compare方法的參數。
  2. 箭頭->把參數列表和主體分隔為兩個部分。
  3. 主體:本例中是把比較口罩品牌的表達式作為Lambda表達式的返回。主體可以修改成另外一種寫法,含義是一樣的:
maskList.sort((Mask o1, Mask o2) -> {
    return o1.getBrand().compareTo(o2.getBrand());
});

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。

Lambda表達式的基本語法

從上面的例子中的兩個種寫法中,可以看出Lambda表達式有兩種基本語法,分別如下:

  1. (參數列表) -> 表達式
  2. (參數列表) -> { 多條語句 }

只看這兩條干癟的語法,理解起來比較困難,實踐出真知,我們來多舉幾個例子。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。

Lambda表達式示例

  1. 我們提到的例子,Lambda表達式的參數列表有兩個Mask類型的參數,主體是比較兩個Mask對象的品牌,返回的是一個int類型。當主體是一個表達式時,不需要return語句,隱含return該表達式的返回值。
(Mask o1, Mask o2) -> o1.getBrand().compareTo(o2.getBrand())
  1. 參數列表中僅有一個Mask類型的參數,返回的是一個String類型,是該Mask對象的品牌信息。
(Mask mask) -> mask.getBrand()
  1. 參數列表中僅有一個Mask類型的參數,返回的是一個boolean類型,是該Mask對象的類型是否為N95。
(Mask mask) -> mask.getType() == "N95"
  1. 參數列表中沒有任何參數,返回的是一個int類型。
() -> 996
  1. 參數列表中有兩個int類型的參數,但是沒有返回值(void)。在主體中可以寫多條語句,不過記住要用{}將其包裹。
(int x, int y) -> {
    System.out.println("萬貓學社想對你說:");
    System.out.println("第一個參數是:" + x);
    System.out.println("第二個參數是:" + y);
    System.out.println("兩數之和是:" + (x + y));
}

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。

小測試

看了這么多的例子,是不是擼胳膊挽袖子准備大干一場?別急,檢驗出真知,我們先簡單測試一下。以下的Lambda表達式有哪幾個是正確的?

  1. () -> {}
  2. () -> "萬貓學社"
  3. () -> { "萬貓學社" }
  4. () -> { return "萬貓學社"; }
  5. () -> return "萬貓學社";

請思考片刻…
.
.
.

.
.
.

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。

宣布答案:第1、2和4個是正確的,第3和5個是錯誤的。我們來逐個分析一下:

  1. () -> {}:正確,這個Lambda表達式沒有參數,也沒有任何返回。
  2. () -> "萬貓學社":正確,這個Lambda表達式沒有參數,主體是一個表達式,返回String類型。
  3. () -> { "萬貓學社" }:錯誤, "萬貓學社"是一個表達式,不是一個語句,不能使用{}將其包裹,可以修改為() -> "萬貓學社"
  4. () -> { return "萬貓學社"; }:正確,這個Lambda表達式沒有參數,主體是一個語句,使用{}將其包裹,返回String類型。
  5. () -> return "萬貓學社"; :錯誤, return "萬貓學社";是一個語句,不是一個表達式,必須使用{}將其包裹,可以修改為() -> { return "萬貓學社"; }

如果你全部答對,恭喜你,你已經基本掌握Lambda表達式的基本語法;如果你有答錯的,沒關系,重新再看一遍,再復習鞏固一下。
學習的路上,我與你一起前行。

《死磕Lambda表達式》系列

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM