該如何使用? 什么是 Lambda?

什么是 Lambda?(該如何使用?)

該如何使用? 什么是 Lambda?

文章插圖

1.什么是Lambda?
我們知道,對于一個Java變量,我們可以賦給其一個“值” 。
該如何使用? 什么是 Lambda?

文章插圖

如果你想把“一塊代碼”賦給一個Java變量,應該怎么做呢?
比如,我想把右邊那塊代碼,賦給一個叫做aBlockOfCode的Java變量:
該如何使用? 什么是 Lambda?

文章插圖

在Java 8之前,這個是做不到的 。 但是Java 8問世之后,利用Lambda特性,就可以做到了 。
該如何使用? 什么是 Lambda?

文章插圖

當然,這個并不是一個很簡潔的寫法 。 所以,為了使這個賦值操作更加elegant, 我們可以移除一些沒用的聲明 。
該如何使用? 什么是 Lambda?

文章插圖

這樣,我們就成功的非常優雅的把“一塊代碼”賦給了一個變量 。 而“這塊代碼”,或者說“這個被賦給一個變量的函數”,就是一個Lambda表達式 。
但是這里仍然有一個問題,就是變量aBlockOfCode的類型應該是什么?
在Java 8里面,所有的Lambda的類型都是一個接口,而Lambda表達式本身,也就是”那段代碼“,需要是這個接口的實現 。 這是我認為理解Lambda的一個關鍵所在,簡而言之就是,Lambda表達式本身就是一個接口的實現 。 直接這樣說可能還是有點讓人困擾,我們繼續看看例子 。
我們給上面的aBlockOfCode加上一個類型:
該如何使用? 什么是 Lambda?

文章插圖

這種只有一個接口函數需要被實現的接口類型,我們叫它”函數式接口“ 。 為了避免后來的人在這個接口中增加接口函數導致其有多個接口函數需要被實現,變成"非函數接口”,我們可以在這個上面加上一個聲明@FunctionalInterface, 這樣別人就無法在里面添加新的接口函數了:
該如何使用? 什么是 Lambda?

文章插圖

這樣,我們就得到了一個完整的Lambda表達式聲明:
該如何使用? 什么是 Lambda?

文章插圖

2.Lambda表達式有什么作用?
最直觀的作用就是使得代碼變得異常簡潔 。
我們可以對比一下Lambda表達式和傳統的Java對同一個接口的實現:
該如何使用? 什么是 Lambda?

文章插圖

這兩種寫法本質上是等價的 。 但是顯然,Java 8中的寫法更加優雅簡潔 。 并且,由于Lambda可以直接賦值給一個變量,我們就可以直接把Lambda作為參數傳給函數, 而傳統的Java必須有明確的接口實現的定義,初始化才行:
該如何使用? 什么是 Lambda?

文章插圖

有些情況下,這個接口實現只需要用到一次 。 傳統的Java 7必須要求你定義一個“污染環境”的接口實現MyInterfaceImpl,而相較之下Java 8的Lambda, 就顯得干凈很多 。
Lambda結合FunctionalInterface Lib, forEach, stream(),method reference等新特性可以使代碼變的更加簡潔!Lambda推薦:Lambda完整學習指南!
直接上例子 。
假設Person的定義和List的值都給定 。
該如何使用? 什么是 Lambda?

文章插圖

現在需要你打印出guiltyPersons List里面所有LastName以"Z"開頭的人的FirstName 。
原生態Lambda寫法:定義兩個函數式接口,定義一個靜態函數,調用靜態函數并給參數賦值Lambda表達式 。
該如何使用? 什么是 Lambda?

文章插圖

這個代碼實際上已經比較簡潔了,但是我們還可以更簡潔么?
當然可以 。 在Java 8中有一個函數式接口的包,里面定義了大量可能用到的函數式接口(java.util.function (Java Platform SE 8 )) 。
所以,我們在這里壓根都不需要定義NameChecker和Executor這兩個函數式接口,直接用Java 8函數式接口包里的Predicate和Consumer就可以了——因為他們這一對的接口定義和NameChecker/Executor其實是一樣的 。
該如何使用? 什么是 Lambda?

文章插圖

第一步簡化 - 利用函數式接口包:
該如何使用? 什么是 Lambda?

文章插圖

推薦閱讀