Lambda (轉)

1什么是Lambda?

我們知道蜡塌,對于一個Java變量,我們可以賦給其一個“值”

如果你想把“一塊代碼”賦給一個Java變量,應該怎么做呢舌狗?

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

在Java 8之前把夸,這個是做不到的而线。但是Java 8問世之后铭污,利用Lambda特性,就可以做到了膀篮。

當然嘹狞,這個并不是一個很簡潔的寫法。所以誓竿,為了使這個賦值操作更加elegant, 我們可以移除一些沒用的聲明磅网。

這樣,我們就成功的非常優(yōu)雅的把“一塊代碼”賦給了一個變量筷屡。而“這塊代碼”涧偷,或者說“這個被賦給一個變量的函數”,就是一個Lambda表達式毙死。

但是這里仍然有一個問題燎潮,就是變量aBlockOfCode的類型應該是什么?

在Java 8里面扼倘,所有的Lambda的類型都是一個接口确封,而Lambda表達式本身,也就是”那段代碼“再菊,需要是這個接口的實現(xiàn)爪喘。這是我認為理解Lambda的一個關鍵所在,簡而言之就是纠拔,Lambda表達式本身就是一個接口的實現(xiàn)秉剑。直接這樣說可能還是有點讓人困擾,我們繼續(xù)看看例子稠诲。我們給上面的aBlockOfCode加上一個類型:

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

這樣岗仑,我們就得到了一個完整的Lambda表達式聲明:

2Lambda表達式有什么作用?

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

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

(點擊看大圖)

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

(點擊看大圖)

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

Lambda結合FunctionalInterface Lib, forEach, stream()五续,method reference等新特性可以使代碼變的更加簡潔!

直接上例子龄恋。

假設Person的定義和List<Person>的值都給定疙驾。

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

原生態(tài)Lambda寫法:定義兩個函數式接口郭毕,定義一個靜態(tài)函數它碎,調用靜態(tài)函數并給參數賦值Lambda表達式。

這個代碼實際上已經比較簡潔了显押,但是我們還可以更簡潔么扳肛?

當然可以。在Java 8中有一個函數式接口的包乘碑,里面定義了大量可能用到的函數式接口(java.util.function (Java Platform SE 8 ))挖息。所以,我們在這里壓根都不需要定義NameChecker和Executor這兩個函數式接口蝉仇,直接用Java 8函數式接口包里的Predicate<T>和Consumer<T>就可以了——因為他們這一對的接口定義和NameChecker/Executor其實是一樣的旋讹。

第一步簡化 – 利用函數式接口包:

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

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

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

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

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

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

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

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

這里假設我們有一個person object扛稽,以及一個person object的Optional wrapper:

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

只有當Optional<T>結合Lambda一起使用的時候在张,才能發(fā)揮出其真正的威力用含!

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

情況一 – 存在則開干

情況二 – 存在則返回耕餐,無則返回屁

情況三 – 存在則返回凡傅,無則由函數產生

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

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

關于Java的Lambda, 還有東西需要討論和學習壹蔓。比如如何handle lambda exception,如何利用Lambda的特性來進行parallel processing等猫态∮度兀總之,我只是一如既往地介紹個大概亲雪,讓你大概知道勇凭,哦!原來是這樣子就OK了义辕。網上關于Lambda有很多相關的教程虾标,多看多練。假以時日灌砖,必定有所精益璧函。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末傀蚌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蘸吓,更是在濱河造成了極大的恐慌善炫,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件库继,死亡現(xiàn)場離奇詭異销部,居然都是意外死亡,警方通過查閱死者的電腦和手機制跟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門舅桩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人雨膨,你說我怎么就攤上這事擂涛。” “怎么了聊记?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵撒妈,是天一觀的道長。 經常有香客問我排监,道長狰右,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任舆床,我火速辦了婚禮棋蚌,結果婚禮上,老公的妹妹穿的比我還像新娘挨队。我一直安慰自己谷暮,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布盛垦。 她就那樣靜靜地躺著湿弦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腾夯。 梳的紋絲不亂的頭發(fā)上颊埃,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音蝶俱,去河邊找鬼班利。 笑死,一個胖子當著我的面吹牛跷乐,可吹牛的內容都是我干的肥败。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馒稍!你這毒婦竟也來了皿哨?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤纽谒,失蹤者是張志新(化名)和其女友劉穎证膨,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體鼓黔,經...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡央勒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澳化。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崔步。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缎谷,靈堂內的尸體忽然破棺而出井濒,到底是詐尸還是另有隱情,我是刑警寧澤列林,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布瑞你,位于F島的核電站,受9級特大地震影響希痴,放射性物質發(fā)生泄漏者甲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一砌创、第九天 我趴在偏房一處隱蔽的房頂上張望虏缸。 院中可真熱鬧,春花似錦纺铭、人聲如沸寇钉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谦秧,卻和暖如春竟纳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疚鲤。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工锥累, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人集歇。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓桶略,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子际歼,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354