亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                現(xiàn)代編程語(yǔ)言都具備的Lambda到底是個(gè)啥?詳聊Lambda與函數(shù)式接口

                1. Lambda

                咱們首先來(lái)說(shuō)說(shuō) Lambda 這個(gè)名字,Lambda 并不是一個(gè)什么的縮寫,它是希臘第十一個(gè)字母 λ 的讀音,同時(shí)它也是微積分函數(shù)中的一個(gè)概念,所表達(dá)的意思是一個(gè)函數(shù)入?yún)⒑统鰠?span id="g9eyoi5" class="wpcom_tag_link">定義,在編程語(yǔ)言中其實(shí)是借用了數(shù)學(xué)中的 λ,并且多了一點(diǎn)含義,在編程語(yǔ)言中功能代表它具體功能的叫法是匿名函數(shù)(Anonymous Function),根據(jù)百科的解釋:

                匿名函數(shù)(英語(yǔ):Anonymous Function)在計(jì)算機(jī)編程中是指一類無(wú)需定義標(biāo)識(shí)符(函數(shù)名)的函數(shù)或子程序。

                到這我們應(yīng)該看懂了,在編程語(yǔ)言中引入了 λ 的數(shù)學(xué)中的意思后,還加入了“匿名”這個(gè)概念,為什么要加它呢?顯然是為了讓開發(fā)者寫起來(lái)更加方便,不必去想具體的函數(shù)名,尤其是在流式表達(dá)中,匿名能讓你更加高效。

                接著再來(lái)說(shuō)說(shuō)Lambda 的歷史,雖然它在 JDK8 發(fā)布之后才正式出現(xiàn),但是在編程語(yǔ)言界,它是一個(gè)具有悠久歷史的東西,最早在 1958 年在Lisp 語(yǔ)言中首先采用,而且雖然Java脫胎于C++,但是C++在2011年已經(jīng)發(fā)布了Lambda 了,但是 JDK8 的 LTS 在2014年才發(fā)布,所以 Java 被人叫做老土不是沒有原因的,現(xiàn)代編程語(yǔ)言則是全部一出生就自帶 Lambda 支持,所以Lambda 其實(shí)是越來(lái)越火的一個(gè)節(jié)奏~

                那么Lambda 到底好在哪?不用寫函數(shù)名?其實(shí)我覺得要回答這個(gè)問(wèn)題首先要明白Lambda 在編程語(yǔ)言方面到底是什么?

                上面也說(shuō)了,Lambda 在編程語(yǔ)言中往往是一個(gè)匿名函數(shù),也就是說(shuō)Lambda 是一個(gè)抽象概念,而編程語(yǔ)言提供了配套支持,比如在 Java 中其實(shí)為L(zhǎng)ambda 進(jìn)行配套的就是函數(shù)式接口,通過(guò)函數(shù)式接口生成匿名類和方法進(jìn)行Lambda 式的處理。

                那么,既然是這一套規(guī)則我們明白了,那么Lambda 所提供的好處在Java中就是函數(shù)式接口所提供的能力了,函數(shù)式接口往往則是提供了一些通用能力,這些函數(shù)式接口在JDK中也有一套完整的實(shí)踐,那就是 Stream。

                Stream 提供了一套完整的流式處理方法幫助我們進(jìn)行流式調(diào)用,熟悉Stream 的讀者應(yīng)該知道使用它能帶來(lái)多么大的便捷,更多關(guān)于 Stream 的知識(shí)可以看我的 延遲執(zhí)行與不可變,系統(tǒng)講解JavaStream數(shù)據(jù)處理 ,在這篇文章中有著詳細(xì)的敘述。

                那么總結(jié)起來(lái),Lambda 在Java中所提供的好處就是使用函數(shù)式接口對(duì)一些問(wèn)題進(jìn)行了抽象,從而得到了一些通用能力,這些通用能力就是使用Lambda 最大的好處,下面將會(huì)具體講解JDK中都定義了哪些通用能力,看到這的小伙伴可以給本文點(diǎn)個(gè)贊,以示鼓勵(lì)。

                2. 函數(shù)式接口

                在 Java 中,所有的函數(shù)式接口都是以 @Functionallnterface 進(jìn)行標(biāo)注的,就像這樣:

                @FunctionalInterfacepublic interface Runnable { public abstract void run();}復(fù)制代碼

                在一個(gè)接口上打上 @Functionallnterface并且定義一個(gè)抽象方法,這樣的類我們就稱之為函數(shù)式接口,當(dāng)然這個(gè)方法并不一定非要用抽象關(guān)鍵字來(lái)修飾,比如:

                @FunctionalInterfacepublic interface Consumer { void accept(T t);}復(fù)制代碼

                當(dāng)然,不寫 @Functionallnterface 注解其實(shí)也沒關(guān)系,但是需要保證,這個(gè)接口只定義了一個(gè)抽象方法,接口的默認(rèn)方法不算,那個(gè)可以稱得上是接口的靜態(tài)方法了。

                為什么只能有一個(gè)抽象方法呢?因?yàn)槟愕淖远x邏輯就是這個(gè)方法的匿名函數(shù),最終會(huì)調(diào)用這個(gè)方法,所以只能有一個(gè)。

                然后你就可以使用 Lambda 表達(dá)式來(lái)進(jìn)行書寫了,就像這樣:

                Thread thread = new Thread(() -> { });復(fù)制代碼

                看吧,很方便的寫法就定義了一個(gè)Runnable 的匿名子類出來(lái),不過(guò) Runnable 這種使用Lambda 只是為了生成一個(gè)匿名子類的情況確實(shí)無(wú)法完全發(fā)揮Lambda 的作用,Lambda 更大的作用還是在解決具體的問(wèn)題上,而非創(chuàng)造一個(gè)匿名類。

                舉個(gè)例子,假如你想定義一個(gè)對(duì)商品數(shù)據(jù)進(jìn)行商品篩查的函數(shù),那么它可能是這樣的:

                public List filter(List list, String type) { List result = new ArrayList(); for (Goods goods : list) { if (goods.getType().equals(type)) { result.add(goods); } } return result; }復(fù)制代碼

                ok,看起來(lái)一切沒問(wèn)題,但是架不住需求改變啊,很快你又需要定義一個(gè)對(duì)商品金額進(jìn)行篩查的方法,那么它可能是這樣的:

                public List gt(List list, Integer price) { List result = new ArrayList(); for (Goods goods : list) { if (goods.getPrice() > price) { result.add(goods); } } return result; }復(fù)制代碼

                那么你可以發(fā)現(xiàn):大部分代碼基本沒變,只有入?yún)⒑团袛噙壿嫲l(fā)生了一點(diǎn)改變,這個(gè)時(shí)候你可能會(huì)想,能不能把判斷邏輯直接抽象成一個(gè)匿名函數(shù),每次只需要簡(jiǎn)單寫一個(gè)這個(gè)判斷函數(shù)即可,再把方法入?yún)⒎庋b成一個(gè)東西,在任何場(chǎng)景下都可以使用。

                看到這,你可能就有點(diǎn)明白了,因?yàn)樵贘ava8 已經(jīng)提供了Stream流去做這件事,上面這個(gè)場(chǎng)景其實(shí)對(duì)應(yīng)的是Stream 中的filter 方法,而filter 方法的入?yún)⒕褪且粋€(gè)函數(shù)式接口——Predicate。

                還沒明白嗎?那我說(shuō)的再清楚一點(diǎn),Predicate 抽象了判斷這個(gè)場(chǎng)景,而且這種抽象不局限于業(yè)務(wù),是直接對(duì)某一類場(chǎng)景進(jìn)行抽象,比如篩選商品類別,篩選商品大于某個(gè)金額或者小于某個(gè)金額,它不在糾結(jié)你到底想要怎么篩選,而是直接對(duì)篩選函數(shù)進(jìn)行抽象,得到了Predicate,你想怎么篩選你自己寫,剩下的交給它,它將一勞永逸的解決這類問(wèn)題,當(dāng)然這里面還有一部分 Stream 的功勞,不過(guò)主要思想還是 Predicate 在做,Stream 這里我們暫且不提。

                像這種對(duì)于某個(gè)場(chǎng)景進(jìn)行頂級(jí)抽象的函數(shù)式接口,JDK一共提供了四個(gè):

              1. Consumer
              2. Supplier
              3. Predicate
              4. Function
              5. 接下來(lái)我將一一為大家進(jìn)行講述,除了這四個(gè)之外還有大量的衍生函數(shù)式接口,在JDK8中就有50個(gè)左右,不過(guò)都是在這四個(gè)基礎(chǔ)上進(jìn)行修改,不必?fù)?dān)心記不住的問(wèn)題。

                3. Consumer

                **Consumer **通過(guò)名字可以看出它是一個(gè)消費(fèi)函數(shù)式接口,主要針對(duì)的是消費(fèi)這個(gè)場(chǎng)景,它的代碼定義如下:

                @FunctionalInterfacepublic interface Consumer { void accept(T t);}復(fù)制代碼

                通過(guò)泛型 T 定義了一個(gè)入?yún)?,但是沒有返回值,它代表你可以針對(duì)這個(gè)入?yún)⒆鲆恍┳远x邏輯,比較典型的例子是 Stream 中的 forEach 方法。

                而我們的主要使用場(chǎng)景也往往是循環(huán)進(jìn)行某項(xiàng)操作,比如有一堆手機(jī)號(hào),循環(huán)進(jìn)行發(fā)短信。

                所以消費(fèi)場(chǎng)景是 Consumer 的主要用武之地,但是有時(shí)候你還面臨一個(gè)問(wèn)題,一個(gè)入?yún)⑺坪跆倭?,有時(shí)候你需要對(duì)兩個(gè)對(duì)象進(jìn)行操作,又懶得將它們合并成一個(gè)對(duì)象,這種情況 JDK 提供了 BiConsumer:

                @FunctionalInterfacepublic interface BiConsumer { void accept(T t, U u);}復(fù)制代碼

                這種你可以直接傳進(jìn)去兩個(gè)參數(shù)了,什么?你想要三個(gè)參數(shù)的?那沒有,三個(gè)或者三個(gè)以上我感覺就有必要合并成一個(gè)對(duì)象進(jìn)行消費(fèi)了。

                除了這兩個(gè)之外,還有DoubleConsumer、IntConsumer和LongConsumer這種限定了入?yún)㈩愋偷?Consumer,這里不再多述。

                4. Supplier

                Supplier通過(guò)名字比較難看出來(lái)它是一個(gè)場(chǎng)景的函數(shù)式接口,它主要針對(duì)的是get這個(gè)場(chǎng)景或者說(shuō)獲取這個(gè)場(chǎng)景,它的代碼定義如下:

                @FunctionalInterfacepublic interface Supplier { T get();}復(fù)制代碼

                通過(guò)泛型 T 定義了一個(gè)返回值類型,但是沒有入?yún)ⅲ砟憧梢葬槍?duì)調(diào)用方獲取某個(gè)值,比較典型的例子是 Stream 中的 collect 方法,通過(guò)自定義傳入我們想要取得的某種對(duì)象進(jìn)行對(duì)象收集。

                而我們的主要使用場(chǎng)景也往往是收集和聚合這個(gè)場(chǎng)景了,這個(gè)場(chǎng)景我們也是對(duì)獲得這個(gè)場(chǎng)景進(jìn)行收集。

                和Consumer一樣,Supplier還具有以下衍生接口:

              6. BooleanSupplier
              7. DoubleSupplier
              8. IntSupplier
              9. LongSupplier
              10. 都是提前對(duì)獲取的定義好了數(shù)據(jù)類型,思想一致,這里不再多述。

                5. Predicate

                Predicate前文我們已經(jīng)介紹過(guò),它主要針對(duì)的是判斷這個(gè)場(chǎng)景,它的代碼定義如下:

                @FunctionalInterfacepublic interface Predicate { boolean test(T t);}復(fù)制代碼

                通過(guò)泛型 T 定義了一個(gè)入?yún)ⅲ祷亓艘粋€(gè)布爾值,它代表你可以傳入一段判斷邏輯的函數(shù),比較典型的例子是 Stream 中的 filter方法。

                我們對(duì)于它的使用場(chǎng)景實(shí)在是太多了,基本上做任何業(yè)務(wù)都有在內(nèi)存中進(jìn)行篩選 or 判斷的場(chǎng)景。

                所以判斷和篩選場(chǎng)景是 Predicate的主要用武之地,但是有時(shí)候你還面臨和上面一樣的問(wèn)題,一個(gè)入?yún)⑺坪跆倭耍袝r(shí)候你需要對(duì)兩個(gè)對(duì)象進(jìn)行操作,又懶得將它們合并成一個(gè)對(duì)象,這種情況 JDK 提供了 BiPredicate:

                @FunctionalInterfacepublic interface BiPredicate { boolean test(T t, U u);}復(fù)制代碼

                這種你可以直接傳進(jìn)去兩個(gè)參數(shù)進(jìn)行函數(shù)的自定義邏輯。

                除了這兩個(gè)之外,還有DoublePredicate、IntPredicate和LongPredicate這種限定了入?yún)㈩愋偷腜redicate,這里不再多述。

                6. Function

                Function 接口的名字不太能輕易看出來(lái)它的場(chǎng)景,它主要針對(duì)的則是 轉(zhuǎn)換這個(gè)場(chǎng)景,其實(shí)說(shuō)轉(zhuǎn)換可能也不太正確,它是一個(gè)覆蓋范圍比較廣的場(chǎng)景,你也可以理解為擴(kuò)展版的Consumer,接口定義如下:

                @FunctionalInterfacepublic interface Function { R apply(T t);}復(fù)制代碼

                通過(guò)一個(gè)入?yún)?T 進(jìn)行自定義邏輯處理,最終得到一個(gè)出參 R,比較典型的例子是 Stream 中的 map 系列方法和 reduce 系列方法。

                為什么我說(shuō)也可以理解為一個(gè)擴(kuò)展版的Consumer呢?我們還舉例手機(jī)號(hào)發(fā)短信的場(chǎng)景好了,你通過(guò)循環(huán)發(fā)完短信之后可能想拿到發(fā)完短信之后的結(jié)果對(duì)象,來(lái)進(jìn)行后續(xù)處理。

                這個(gè)時(shí)候單純的Consumer就不行了,因?yàn)樗鼪]有返回值,你就可以通過(guò) Function 這種函數(shù)式對(duì)象進(jìn)行處理了。

                和 Consumer 一樣,F(xiàn)unction 也有一個(gè)衍生接口可以通過(guò)兩個(gè)入?yún)⒎祷匾粋€(gè)對(duì)象——BiFunction。

                還有一些定義好了入?yún)⒑统鰠⒌?Function

              11. 延遲執(zhí)行與不可變,系統(tǒng)講解JavaStream數(shù)據(jù)處理
              12. 歸約、分組與分區(qū),深入講解JavaStream終結(jié)操作
              13. 鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年7月24日 17:05
                下一篇 2022年7月24日 17:05

                相關(guān)推薦

                • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

                  對(duì)于微商朋友來(lái)說(shuō),朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營(yíng)一個(gè)朋友圈,有的微商看起來(lái)逼格滿滿,實(shí)際效果也不錯(cuò);而有的卻動(dòng)都不動(dòng)就被屏蔽甚至拉黑…

                  2022年11月27日
                • 存儲(chǔ)過(guò)程語(yǔ)法(sql server存儲(chǔ)過(guò)程語(yǔ)法)

                  今天小編給各位分享存儲(chǔ)過(guò)程語(yǔ)法的知識(shí),其中也會(huì)對(duì)sql server存儲(chǔ)過(guò)程語(yǔ)法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問(wèn)題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲(chǔ)過(guò)程基本語(yǔ)法…

                  2022年11月26日
                • 《寶可夢(mèng)朱紫》夢(mèng)特性怎么獲得?隱藏特性獲取方法推薦

                  寶可夢(mèng)朱紫里有很多寶可夢(mèng)都是擁有夢(mèng)特性會(huì)變強(qiáng)的寶可夢(mèng),很多玩家不知道夢(mèng)特性怎么獲得,下面就給大家?guī)?lái)寶可夢(mèng)朱紫隱藏特性獲取方法推薦,感興趣的小伙伴一起來(lái)看看吧,希望能幫助到大家。 …

                  2022年11月25日
                • 《寶可夢(mèng)朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

                  寶可夢(mèng)朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)?lái)寶可夢(mèng)朱紫奇魯莉安進(jìn)化方法分享,感興趣的小伙伴一起來(lái)看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

                  2022年11月25日
                • 成都健康碼打不開顯示接口請(qǐng)求未知異常怎么辦(成都健康碼打不開顯示接口請(qǐng)求未知異常)

                  成都這幾天的疫情也是備受關(guān)注,疫情期間各地出行都是需要查看健康碼的,不過(guò)今天卻有成都的小伙伴反饋健康碼無(wú)法打開的情況。成都健康碼打不開顯示接口請(qǐng)求未知異常怎么辦?由于健康碼無(wú)法打開…

                  2022年11月24日
                • 1千克等于多少磅

                  克,此定義在1958年被美國(guó)以及其他英聯(lián)邦會(huì)員國(guó)承認(rèn)換算回來(lái),一千克等于262磅,一磅等于037千克英國(guó)在1963年開始,依據(jù)度量衡法案的規(guī);1 磅=16 盎司=04536 千克 …

                  2022年11月24日
                • 《寶可夢(mèng)朱紫》暴飛龍?jiān)趺醋ィ勘╋w龍獲得方法

                  寶可夢(mèng)朱紫暴飛龍位置在哪?在游戲中,很多玩家還不清楚暴飛龍具體要怎么樣獲得,其實(shí)獲得方法很簡(jiǎn)單,暴飛龍直接是沒得抓的,需要玩家從寶貝龍進(jìn)化得到,下面一起來(lái)看一下寶可夢(mèng)朱紫暴飛龍獲得…

                  2022年11月23日
                • 《寶可夢(mèng)朱紫》布土撥怎么進(jìn)化?布土撥進(jìn)化方法介紹

                  寶可夢(mèng)朱紫中,不同的寶可夢(mèng)有不同的進(jìn)化方法,其中布土撥的進(jìn)化方法是比較特殊的。很多玩家不知道寶可夢(mèng)朱紫布土撥怎么進(jìn)化,下面就帶來(lái)寶可夢(mèng)朱紫布土撥進(jìn)化方法介紹,一起來(lái)看看吧,希望能幫…

                  2022年11月23日
                • 《寶可夢(mèng)朱紫》薄荷怎么獲得?薄荷獲得方法

                  寶可夢(mèng)朱紫中薄荷有改變寶可夢(mèng)的屬性或性格等效果,很多玩家想知道寶可夢(mèng)朱紫薄荷怎么獲得,下面就帶來(lái)寶可夢(mèng)朱紫薄荷獲得方法,感興趣的小伙伴一起來(lái)看看吧,希望能幫助到大家。 薄荷獲得方法…

                  2022年11月23日
                • 《寶可夢(mèng)朱紫》怎么交換精靈?交換精靈方法一覽

                  寶可夢(mèng)朱紫中玩家可以和好友或者npc進(jìn)行交換寶可夢(mèng)獲得自己沒有的寶可夢(mèng),很多玩家想知道寶可夢(mèng)朱紫怎么交換精靈,下面就帶來(lái)寶可夢(mèng)朱紫交換精靈方法一覽,感興趣的小伙伴不要錯(cuò)過(guò),希望能幫…

                  2022年11月23日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息