日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试官 | 什么是 Lambda?该如何使用?

發(fā)布時(shí)間:2025/3/11 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官 | 什么是 Lambda?该如何使用? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者 | Mingqi

來源 | zhihu.com/question/20125256/answer/324121308

1.什么是Lambda?

我們知道,對(duì)于一個(gè)Java變量,我們可以賦給其一個(gè)“值”。


如果你想把“一塊代碼”賦給一個(gè)Java變量,應(yīng)該怎么做呢?

比如,我想把右邊那塊代碼,賦給一個(gè)叫做aBlockOfCode的Java變量:

在Java 8之前,這個(gè)是做不到的。但是Java 8問世之后,利用Lambda特性,就可以做到了。

當(dāng)然,這個(gè)并不是一個(gè)很簡潔的寫法。所以,為了使這個(gè)賦值操作更加elegant, 我們可以移除一些沒用的聲明。

這樣,我們就成功的非常優(yōu)雅的把“一塊代碼”賦給了一個(gè)變量。而“這塊代碼”,或者說“這個(gè)被賦給一個(gè)變量的函數(shù)”,就是一個(gè)Lambda表達(dá)式

但是這里仍然有一個(gè)問題,就是變量aBlockOfCode的類型應(yīng)該是什么?

在Java 8里面,所有的Lambda的類型都是一個(gè)接口,而Lambda表達(dá)式本身,也就是”那段代碼“,需要是這個(gè)接口的實(shí)現(xiàn)。這是我認(rèn)為理解Lambda的一個(gè)關(guān)鍵所在,簡而言之就是,Lambda表達(dá)式本身就是一個(gè)接口的實(shí)現(xiàn)。直接這樣說可能還是有點(diǎn)讓人困擾,我們繼續(xù)看看例子。

我們給上面的aBlockOfCode加上一個(gè)類型:

這種只有一個(gè)接口函數(shù)需要被實(shí)現(xiàn)的接口類型,我們叫它”函數(shù)式接口“。為了避免后來的人在這個(gè)接口中增加接口函數(shù)導(dǎo)致其有多個(gè)接口函數(shù)需要被實(shí)現(xiàn),變成"非函數(shù)接口”,我們可以在這個(gè)上面加上一個(gè)聲明@FunctionalInterface, 這樣別人就無法在里面添加新的接口函數(shù)了:

這樣,我們就得到了一個(gè)完整的Lambda表達(dá)式聲明:

2.Lambda表達(dá)式有什么作用?

最直觀的作用就是使得代碼變得異常簡潔

我們可以對(duì)比一下Lambda表達(dá)式和傳統(tǒng)的Java對(duì)同一個(gè)接口的實(shí)現(xiàn):

這兩種寫法本質(zhì)上是等價(jià)的。但是顯然,Java 8中的寫法更加優(yōu)雅簡潔。并且,由于Lambda可以直接賦值給一個(gè)變量,我們就可以直接把Lambda作為參數(shù)傳給函數(shù), 而傳統(tǒng)的Java必須有明確的接口實(shí)現(xiàn)的定義,初始化才行

有些情況下,這個(gè)接口實(shí)現(xiàn)只需要用到一次。傳統(tǒng)的Java 7必須要求你定義一個(gè)“污染環(huán)境”的接口實(shí)現(xiàn)MyInterfaceImpl,而相較之下Java 8的Lambda, 就顯得干凈很多。

Lambda結(jié)合FunctionalInterface Lib, forEach, stream(),method reference等新特性可以使代碼變的更加簡潔!Lambda推薦:Lambda完整學(xué)習(xí)指南!

直接上例子。

假設(shè)Person的定義和List<Person>的值都給定。

現(xiàn)在需要你打印出guiltyPersons List里面所有LastName以"Z"開頭的人的FirstName。

原生態(tài)Lambda寫法:定義兩個(gè)函數(shù)式接口,定義一個(gè)靜態(tài)函數(shù),調(diào)用靜態(tài)函數(shù)并給參數(shù)賦值Lambda表達(dá)式。

這個(gè)代碼實(shí)際上已經(jīng)比較簡潔了,但是我們還可以更簡潔么?

當(dāng)然可以。在Java 8中有一個(gè)函數(shù)式接口的包,里面定義了大量可能用到的函數(shù)式接口(java.util.function (Java Platform SE 8 ))。

所以,我們在這里壓根都不需要定義NameChecker和Executor這兩個(gè)函數(shù)式接口,直接用Java 8函數(shù)式接口包里的Predicate<T>和Consumer<T>就可以了——因?yàn)樗麄冞@一對(duì)的接口定義和NameChecker/Executor其實(shí)是一樣的。

第一步簡化 - 利用函數(shù)式接口包:

靜態(tài)函數(shù)里面的for each循環(huán)其實(shí)是非常礙眼的。這里可以利用Iterable自帶的forEach()來替代。forEach()本身可以接受一個(gè)Consumer<T> 參數(shù)。

第二步簡化 - 用Iterable.forEach()取代foreach loop:

由于靜態(tài)函數(shù)其實(shí)只是對(duì)List進(jìn)行了一通操作,這里我們可以甩掉靜態(tài)函數(shù),直接使用stream()特性來完成。stream()的幾個(gè)方法都是接受Predicate<T>,Consumer<T>等參數(shù)的(java.util.stream (Java Platform SE 8 ))。你理解了上面的內(nèi)容,stream()這里就非常好理解了,并不需要多做解釋。

第三步簡化 - 利用stream()替代靜態(tài)函數(shù):

對(duì)比最開始的Lambda寫法,這里已經(jīng)非常非常簡潔了。但是如果,我們要求變一下,變成print這個(gè)人的全部信息,及p -> System.out.println(p); 那么還可以利用Method reference來繼續(xù)簡化。所謂Method reference, 就是用已經(jīng)寫好的別的Object/Class的method來代替Lambda expression。格式如下:

第四步簡化 - 如果是println(p),則可以利用Method reference代替forEach中的Lambda表達(dá)式:

這基本上就是能寫的最簡潔的版本了。

Lambda配合Optional<T>可以使Java對(duì)于null的處理變的異常優(yōu)雅

這里假設(shè)我們有一個(gè)person object,以及一個(gè)person object的Optional wrapper:

Optional<T>如果不結(jié)合Lambda使用的話,并不能使原來繁瑣的null check變的簡單。

只有當(dāng)Optional<T>結(jié)合Lambda一起使用的時(shí)候,才能發(fā)揮出其真正的威力!

我們現(xiàn)在就來對(duì)比一下下面四種常見的null處理中,Java 8的Lambda+Optional<T>和傳統(tǒng)Java兩者之間對(duì)于null的處理差異。

情況一 - 存在則開干

情況二 - 存在則返回,無則返回屁

情況三 - 存在則返回,無則由函數(shù)產(chǎn)生

情況四 - 奪命連環(huán)null檢查

由上述四種情況可以清楚地看到,Optional<T>+Lambda可以讓我們少寫很多ifElse塊。尤其是對(duì)于情況四那種奪命連環(huán)null檢查,傳統(tǒng)java的寫法顯得冗長難懂,而新的Optional<T>+Lambda則清新脫俗,清楚簡潔。

關(guān)于Java的Lambda, 還有東西需要討論和學(xué)習(xí)。比如如何handle lambda exception,如何利用Lambda的特性來進(jìn)行parallel processing等。

3.總結(jié)

想要深入的了解Lambda,辦法只有一個(gè):動(dòng)手實(shí)踐起來,實(shí)踐是精通一項(xiàng)技術(shù)的第一步,來把,現(xiàn)在就開始 coding 吧。

【END】

近期熱文

?
  • 面試珍藏:最常見的200多道Java面試題

  • 被一個(gè)熟悉的面試題問懵了:String...

  • 面試官:如何實(shí)現(xiàn)冪等性校驗(yàn)?

  • 年終盤點(diǎn) | 2019年Java面試題匯總篇(附答案)

關(guān)注下方二維碼,訂閱更多精彩內(nèi)容

朕已閱?

總結(jié)

以上是生活随笔為你收集整理的面试官 | 什么是 Lambda?该如何使用?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。