1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        你知道Java 8 的方法引用嗎

        共 2057字,需瀏覽 5分鐘

         ·

        2020-09-10 17:47

        1. 前言

        Java中的方法引用,很多同學(xué)都見過但卻叫不出名字甚至不太會用,在這篇文章中,我們將看到什么是方法引用以及如何使用它。

        2. 方法引用的使用場景

        我們先來看看方法引用的使用:

        new?Random().ints(10)
        ????????.map(i->Math.abs(i))
        ????????.forEach(i?->?System.out.println(i));

        這里我們隨機生成 10 個整數(shù)然后取它們絕對值并一一打印出來。寫法是沒有問題的,但是還是可以再簡化的。

        map方法接受的是一個函數(shù)式接口IntUnaryOperator,那么上面代碼中的i->Math.abs(i)實際上是:

        new?IntUnaryOperator()?{
        ????@Override
        ????public?int?applyAsInt(int?operand)?{
        ????????return?Math.abs(operand);
        ????}
        }

        從上面來看IntUnaryOperator就是代理了Math.abs(int i),參數(shù)列表、返回值都相同,而且沒有摻雜其它額外的邏輯。這一點非常重要,不摻雜其它邏輯才能相互代替。那么就可以通過方法引用來簡化Lambda 表達(dá)式。上面的式子就可以簡化為:

        new?Random().ints(10)
        ????????.map(Math::abs)
        ????????.forEach(System.out::println);

        3. 方法引用

        Java 方法引用Java 8隨著Lambda表達(dá)式引入的新特性??梢灾苯右靡延?strong style="color: black;">Java類或?qū)ο蟮姆椒ɑ驑?gòu)造器。方法引用通常與Lambda表達(dá)式結(jié)合使用以簡化代碼。其使用條件是:Lambda 表達(dá)式的主體僅包含一個表達(dá)式,且 Lambda 表達(dá)式只調(diào)用了一個已經(jīng)存在的方法;被引用的方法的參數(shù)列表和返回值與 Lambda 表達(dá)式的輸入輸出一致

        方法引用正確的演變過程
        不單純的Lambda不能使用方法引用

        3.1 格式

        方法引用的格式為::。也就是被引用的方法所屬的類名和方法名用雙冒號::隔開,構(gòu)造器方法是個例外,引用會用到new關(guān)鍵字,總結(jié)了一下:

        引用方式說明
        靜態(tài)方法引用ClassName :: staticMethodName?例如上面的Math::abs
        構(gòu)造器引用ClassName :: new?例如通過Supplier?返回新實例
        類任意實例方法引用ClassName :: instanceMethodName?例如?String::concat
        類特定實例方法引用instance:: instanceMethodName?例如?this::equals

        4. 關(guān)于可讀性問題

        大部分人認(rèn)為Lambda 表達(dá)式存在閱讀困難的問題,其實不然,這種流水線的結(jié)構(gòu)恰恰增加了可讀性,每一個Lambda 表達(dá)式都可以看作一個執(zhí)行策略,方法引用反而讓你能更加清楚執(zhí)行了什么策略。另外我經(jīng)常見到類似如下的流式寫法:

        new?Random().ints(10)
        ????????.map(operand?->?{
        ????????????System.out.println("operand?=?"?+?operand);
        ????????????return?operand+1;
        ????????})
        ????????.forEach(System.out::println);

        這種"大肚子"寫法的風(fēng)格是不建議在函數(shù)式編程中出現(xiàn)的。最好單獨提出來封裝做方法引用,寫成下面的風(fēng)格:

        public?void?randomInt()?{
        ????new?Random().ints(10)
        ????????????.map(this::selfIncreasing)
        ????????????.forEach(System.out::println);

        }

        //?封裝
        private?int?selfIncreasing(int?self){
        ????System.out.println("self?=?"?+?self);
        ????return?self+1;
        }

        這樣反而可讀性很強,隨機取 10 個數(shù),然后每個數(shù)走個自增并分別打印出來。

        5. 總結(jié)

        方法引用實現(xiàn)在特定場景下Lambda 表達(dá)式的簡化表示,目的在于讓代碼更加簡潔。但是習(xí)慣了傳統(tǒng)Java編程風(fēng)格的同學(xué)上來會不太適應(yīng),希望借助于本文能幫助你解決這個問題。

        注下方公眾號獲取更多編程干貨

        往期推薦

        重磅!GitHub 推出容器鏡像倉庫服務(wù)!

        13 張圖解 Java 中的內(nèi)存模型

        Upwork 發(fā)布最賺錢的編程語言 Top 15

        一次微服務(wù)與IoT的深度探秘與實戰(zhàn)

        2020年最漂亮的Linux發(fā)行版


        瀏覽 82
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久操免费在线视频 | 美女在线抠逼 | 中文字幕在线观看日韩 | 久久在线视频精品 | 一本久道无码 | 中国日逼视频 | 亚洲AV无码成人精品国产五月天 | 深夜激情福利 | 高h重口激h慎宫交h | 亚洲国产中文日韩欧美高清不卡顿 |