最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文徹底掌握Java中的Lambda表達式

 更新時間:2026年01月07日 10:11:09   作者:在地球迷路的怪獸  
Lambda表達式是Java 8引入的一項重要功能,它允許我們以更簡潔和靈活的方式編寫代碼,這篇文章主要介紹了Java中Lambda表達式的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

為什么需要 Lambda 表達式?

Lambda表達式是Java函數(shù)式編程的核心概念之一。同時它也是一個相對難以理解的概念。

那么為什么需要它呢?

Lambda 表達式的出現(xiàn)是為了簡化實現(xiàn)函數(shù)式接口 Functional Interface 的,什么又是函數(shù)式接口呢?

因此再講函數(shù)式接口之前,先來回顧一下 interface 的概念與基本使用。

interface 接口

接口是用來定義一個協(xié)議或約定,它只聲明方法但不提供方法的具體實現(xiàn)。

我們稱這樣的方法為抽象方法 Abstract Method 。

具體方法的實現(xiàn)是由實現(xiàn)這個接口的 class 來提供的:

這樣一來將接口的聲明與具體實現(xiàn)分開,業(yè)務(wù)中就只需要關(guān)心方法,而不需要關(guān)心具體的實現(xiàn)類,從而實現(xiàn)代碼的解耦與模塊化。

假如現(xiàn)在有一個需求,通過一個方法來發(fā)送多種不同類型的消息,比如既可以發(fā)送 Email 消息也可以發(fā)送 SMS 短信消息,這種場景就非常適合使用 Interface 來實現(xiàn)。

我們先定義一個消息發(fā)送的接口:

/**
 * @author TheSea
 * @description 消息接口
 * @createDate 2025/12/28
 */
public interface Message {
    void send();
}

接下來創(chuàng)建一個 Email 類來實現(xiàn)這個 Message 接口:

/**
 * @author TheSea
 * @description 郵件消息類
 * @createDate 2025/12/28
 */
public class Email implements Message{

    private String email;

    @Override
    public void send() {
        System.out.println("這是一份郵件消息.");
    }
}

再來創(chuàng)建一個 Sms 類來實現(xiàn)這個 Message 接口:

/**
 * @author TheSea
 * @description 短信消息類
 * @createDate 2025/12/28
 */
public class Sms implements Message{

    private String phone;

    @Override
    public void send() {
        System.out.println("這是一份手機短信消息.");
    }
}

現(xiàn)在我們來發(fā)送郵件消息,寫一個方法用來負責統(tǒng)一發(fā)送消息:

	// 參數(shù)類型為接口,因為參數(shù)類型為 Message 接口類型,
    // 這就意味著不管傳入的是 Email 還是 Sms 對象,
    // 它們的類都已經(jīng)各自實現(xiàn)了 Message 接口的 send 方法
    // 所以 sendMsg 方法內(nèi)部只需要執(zhí)行 message 的 send 方法
    // 而不需要關(guān)心執(zhí)行的到底是哪個對象的 send 方法
    // 免去了復雜的判斷和切換,這就是面向接口編程的一個典型應(yīng)用場景
    public static void sendMsg(Message message){
        message.send();
    }

現(xiàn)在嘗試發(fā)送郵件消息:

public class Main {
    public static void main(String[] args) {
        //發(fā)送郵件消息
        Message emailMessage = new Email();
        sendMsg(emailMessage);
    }

    // 參數(shù)類型為接口,因為參數(shù)類型為 Message 接口類型,
    // 這就意味著不管傳入的是 Email 還是 Sms 對象,
    // 它們的類都已經(jīng)各自實現(xiàn)了 Message 接口的 send 方法
    // 所以 sendMsg 方法內(nèi)部只需要執(zhí)行 message 的 send 方法
    // 而不需要關(guān)心執(zhí)行的到底是哪個對象的 send 方法
    // 免去了復雜的判斷和切換,這就是面向接口編程的一個典型應(yīng)用場景
    public static void sendMsg(Message message){
        message.send();
    }
}

再來嘗試一下發(fā)送 Sms 消息:

public class Main {
    public static void main(String[] args) {
        //發(fā)送短信消息
        Message smsMessage = new Sms();
        sendMsg(smsMessage);
    }

    // 參數(shù)類型為接口,因為參數(shù)類型為 Message 接口類型,
    // 這就意味著不管傳入的是 Email 還是 Sms 對象,
    // 它們的類都已經(jīng)各自實現(xiàn)了 Message 接口的 send 方法
    // 所以 sendMsg 方法內(nèi)部只需要執(zhí)行 message 的 send 方法
    // 而不需要關(guān)心執(zhí)行的到底是哪個對象的 send 方法
    // 免去了復雜的判斷和切換,這就是面向接口編程的一個典型應(yīng)用場景
    public static void sendMsg(Message message){
        message.send();
    }
}

到這里按照傳統(tǒng)方法,我們已經(jīng)正確的實現(xiàn)和使用了接口,應(yīng)用場景也 OK。

問題的引入

但是我們會發(fā)現(xiàn),要發(fā)送一條消息要經(jīng)過好多個步驟,比如我們發(fā)送 Sms 消息。

我們需要先創(chuàng)建一個 Sms 類,然后去實現(xiàn) Message 接口中的 send() 方法,然后再實例化一個 Sms 對象,再調(diào)用 send 發(fā)送消息,非常繁復。

而 Lambda 表達式的出現(xiàn)就可以幫助我們解決這個問題。

Lambda 表達式

Lambda 表達式可以提供一種簡單快速的方式來實現(xiàn)上述接口,接口的抽象方法的具體實現(xiàn)直接在 Lambda 表達式里面定義即可,而不用像傳統(tǒng)方法那樣創(chuàng)建類然后實現(xiàn)接口的抽象方法、實例化對象最后調(diào)用方法,大大簡化了代碼的編寫流程。

接下來用 Lambda 表達式重新實現(xiàn)一下剛才的例子。

public class Main {
    public static void main(String[] args) {
        // send()方法的實現(xiàn):
        // public void send() {
        //     System.out.println("這是一份郵件消息.");
        // }

        // Lambda 表達式可以直接可以直接實現(xiàn) Message 接口的 send 抽象方法,然后作為參數(shù)傳給 sendMessage
        // () 代表的就是 send() 方法后面的括號,即參數(shù)列表
        // {} 大括號里面的內(nèi)容就是 send() 方法的函數(shù)體
        sendMsg(() ->{
            System.out.println("這是一份郵件消息.");
        });
    }

    // 參數(shù)類型為接口,因為參數(shù)類型為 Message 接口類型,
    // 這就意味著不管傳入的是 Email 還是 Sms 對象,
    // 它們的類都已經(jīng)各自實現(xiàn)了 Message 接口的 send 方法
    // 所以 sendMsg 方法內(nèi)部只需要執(zhí)行 message 的 send 方法
    // 而不需要關(guān)心執(zhí)行的到底是哪個對象的 send 方法
    // 免去了復雜的判斷和切換,這就是面向接口編程的一個典型應(yīng)用場景
    public static void sendMsg(Message message){
        message.send();
    }
}

上面這條 Lambda 表達式就等效于之前用傳統(tǒng)方法實現(xiàn)的 Email 實例對象。

如果 Lambda 的函數(shù)體里只包含一個表達式,那么可以省略大括號進行簡寫:

sendMsg(() -> System.out.println("這是一份郵件消息."));

如果 Lambda 表達式包含多條語句或者需要明確的流程控制,那么就必須要使用大括號。

目前的例子中抽象方法并沒有參數(shù),現(xiàn)在假設(shè)抽象方法有一個參數(shù) name:

public interface Message {
    void send(String name);
}

那么 Lambda 表達式中就需要這么定義:

public class Main {
    public static void main(String[] args) {
        sendMsg((name) -> System.out.println(name + ": 這是一份郵件消息."));
    }

    public static void sendMsg(Message message){
        message.send("TheSea");
    }
}

注意上面的 參數(shù)名 是形參,可以隨便寫,不一定要和接口中聲明的一樣,比如這樣寫也是一樣的效果:

sendMsg((nameInLambda) -> System.out.println(nameInLambda + ": 這是一份郵件消息."));

如果參數(shù)只有一個的話,Lambda 表達式的參數(shù)列表的小括號是可以去掉的:

sendMsg(name -> System.out.println(name + ": 這是一份郵件消息."));

那么如果有多個參數(shù)呢?那就按順序書寫,然后中間用逗號分隔即可,注意必須要帶上小括號嗷:

public interface Message {
    void send(String name, int age);
}
public class Main {
    public static void main(String[] args) {
        sendMsg((name, age) -> System.out.println(name + ": 您" + age + "歲了,這是一份郵件消息."));
    }

    public static void sendMsg(Message message) {
        message.send("TheSea", 18);
    }
}

注意一定要參數(shù)的聲明順序書寫編譯器才能對上號,否則的話會出現(xiàn)下面的荒唐局面:

public class Main {
    public static void main(String[] args) {
        sendMsg((age, name) -> System.out.println(name + ": 您" + age + "歲了,這是一份郵件消息."));
    }

    public static void sendMsg(Message message) {
        message.send("TheSea", 18);
    }
}

以上示例的抽象方法都沒有返回值,我們來看一下有返回值的情況:

public interface Message {
    String send(String name, int age);
}

此時我們之前的 Lambda 表達式就會報錯:

因為我們需要有返回值:

可以看到,如果函數(shù)體只有一條返回語句,像上面這樣寫會報錯,原因是如果只有一條返回語句的話,return 關(guān)鍵字是不需要存在的,可以簡化成下面這樣:

public class Main {
    public static void main(String[] args) {
        sendMsg((age, name) -> "Lambda 表達式的返回值");
    }

    public static void sendMsg(Message message) {
       String res =  message.send("TheSea", 18);
        System.out.println(res);
    }
}

現(xiàn)在把參數(shù)應(yīng)用進去,當函數(shù)體有多條表達式的時候,需要用大括號包圍:

public class Main {
    public static void main(String[] args) {
        sendMsg((name, age) -> {
            System.out.println(name + ": 您" + age + "歲了,這是一份郵件消息.");
            return "Lambda 表達式的返回值";
        });
    }

    public static void sendMsg(Message message) {
       String res =  message.send("TheSea", 18);
        System.out.println(res);
    }
}

另外如果現(xiàn)在我們想改另外一種發(fā)送方式,比如使用 Sms,那么我們現(xiàn)在也不需要再新建一個 Sms 類來實現(xiàn)接口了,直接修改 Lambda 表達式的函數(shù)體就可以:

public class Main {
    public static void main(String[] args) {
        sendMsg((name, age) -> {
            System.out.println(name + ": 您" + age + "歲了,這是一份短信消息.");
            return "Lambda 表達式的返回值";
        });
    }

    public static void sendMsg(Message message) {
       String res =  message.send("TheSea", 18);
        System.out.println(res);
    }
}

Lambda 表達式也可以像普通對象那樣賦值給變量,如下:

public class Main {
    public static void main(String[] args) {
        Message lambda = (name, age) -> {
            System.out.println(name + ": 您" + age + "歲了,這是一份短信消息.");
            return "Lambda 表達式的返回值";
        };
        
        sendMsg(lambda);
    }

    public static void sendMsg(Message message) {
       String res =  message.send("TheSea", 18);
        System.out.println(res);
    }
}

綜上所述,Lambda 讓我們實現(xiàn)接口抽象方法的整個過程變得非常簡單。

那么 Lambda 表達式是不是可以應(yīng)用在任何形式的 interface 上呢?

當然不行!

Lambda 表達式只能應(yīng)用于有且只有一個抽象方法的接口上,我們稱這樣的接口為函數(shù)式接口。

那為什么Java要這么定義呢?

因為一個接口如果有多個抽象方法的話,那么在使用 Lambda 表達式的時候 Java 將無法確定 Lambda 試圖實現(xiàn)哪一個抽象方法,而當只有一個抽象方法的時候?qū)τ?Java 來說意圖就非常明確。

因此只有函數(shù)式接口才可以使用 Lambda 表達式。

另外,我們可以使用 @FunctionalInterface 注解來標識該接口為一個函數(shù)式接口:

@FunctionalInterface
public interface Message {
    String send(String name, int age);
}

這個注解是可選的,因為函數(shù)式接口定義的本身并不依賴于這個注解,即便不標注但只要符合函數(shù)式接口的定義條件,Java自動就會把它當成是函數(shù)式接口。

不過工程開發(fā)中我們還是建議使用該注解來進行標識,這樣的話如果出現(xiàn)多余一個抽象方法或者是沒有抽象方法的時候就會編譯報錯,同時也會提供一個非常好的語義方便工程師更好的理解該接口的設(shè)計意圖。

總結(jié)

Lambda 表達式歸根到底是一種語法糖,用于簡化函數(shù)式接口的實現(xiàn)。

在 Java 的函數(shù)式編程中起到了關(guān)鍵的作用,Java 標準庫中也包含了非常多的內(nèi)置的函數(shù)式接口,比如 Predicate、Function、Consumer、Supplier 等等,經(jīng)常與 Stream API 結(jié)合使用。

所以掌握 Lambda 表達式是非常重要的。

到此這篇關(guān)于Java中Lambda表達式的文章就介紹到這了,更多相關(guān)Java中Lambda表達式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實現(xiàn)連接mysql數(shù)據(jù)庫單元測試查詢數(shù)據(jù)的實例代碼

    java實現(xiàn)連接mysql數(shù)據(jù)庫單元測試查詢數(shù)據(jù)的實例代碼

    下面小編就為大家?guī)硪黄猨ava實現(xiàn)連接mysql數(shù)據(jù)庫單元測試查詢數(shù)據(jù)的實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • SpringBoot整合junit與Mybatis流程詳解

    SpringBoot整合junit與Mybatis流程詳解

    這篇文章主要介紹了SpringBoot整合第三方技術(shù),包括整合Junit、整合Mybatis,本文通過實例代碼相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • Spring Boot使用模板引擎JSP實例解析

    Spring Boot使用模板引擎JSP實例解析

    這篇文章主要介紹了Spring Boot使用模板引擎JSP實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • MyBatis方法重載的陷阱及解決方案

    MyBatis方法重載的陷阱及解決方案

    在使用 MyBatis 進行開發(fā)時,尤其是使用注解模式(如 @Select、@Insert 等)時,開發(fā)者常常會遇到這樣一個問題:為什么我的方法重載不能正常工作?這篇文章將深入探討 MyBatis 的這個特性及如何規(guī)避相關(guān)的坑,需要的朋友可以參考下
    2024-09-09
  • Java并發(fā)編程總結(jié)——慎用CAS詳解

    Java并發(fā)編程總結(jié)——慎用CAS詳解

    下面小編就為大家?guī)硪黄狫ava并發(fā)編程總結(jié)——慎用CAS詳解。小編覺得挺不錯的, 現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Java面試必考之如何在項目中優(yōu)雅的拋出異常

    Java面試必考之如何在項目中優(yōu)雅的拋出異常

    這篇文章主要為大家詳細介紹了Java中的幾種異常關(guān)鍵字和異常類相關(guān)知識,本文比較適合剛?cè)肟覬ava的小白以及準備秋招的大佬閱讀,需要的可以收藏一下
    2023-06-06
  • springboot2中session超時,退到登錄頁面方式

    springboot2中session超時,退到登錄頁面方式

    這篇文章主要介紹了springboot2中session超時,退到登錄頁面方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java構(gòu)造方法實例詳解(動力節(jié)點java學院整理)

    Java構(gòu)造方法實例詳解(動力節(jié)點java學院整理)

    其實java構(gòu)造方法很簡單,下面通過示例給大家分享java構(gòu)造方法,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-04-04
  • springboot中@RequestParam和@PathVariable區(qū)別

    springboot中@RequestParam和@PathVariable區(qū)別

    本文主要介紹了springboot中@RequestParam和@PathVariable區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-07-07
  • Java詳解多線程協(xié)作作業(yè)之信號同步

    Java詳解多線程協(xié)作作業(yè)之信號同步

    信號量同步是指在不同線程之間,通過傳遞同步信號量來協(xié)調(diào)線程執(zhí)行的先后次序。CountDownLatch是基于時間維度的Semaphore則是基于信號維度的
    2022-05-05

最新評論

西吉县| 蓬莱市| 湟中县| 杂多县| 明星| 阿拉尔市| 沁阳市| 高青县| 杭锦后旗| 九台市| 方山县| 英超| 余庆县| 十堰市| 铁岭市| 广西| 镇雄县| 嘉义市| 拉萨市| 普陀区| 保山市| 慈溪市| 剑川县| 安泽县| 赤壁市| 三门县| 汉寿县| 韩城市| 永吉县| 商河县| 隆林| 东辽县| 安丘市| 通许县| 临高县| 山阳县| 福海县| 特克斯县| 临猗县| 玉龙| 巴彦淖尔市|