Java 8 初探 - Lambda

閱讀時間約 6 分鐘
此為過去的舊文,2014 年 3 月 20 日初次發表於 logdown。

Java 8 終於在 2014 的 3 月 18 日正式釋出了,不過自從用 Objective C 開發 iOS App後,我已經有好一陣子沒碰 Java,期間曾經有短暫寫一點點,但卻沒有時間去用 beta 版的 Java 8,直到最近才又開始玩一下。

Java 8 最亮眼的特色之一應該就是所謂的 Lambda 表示法,Lambda 表示法幾乎內建在很多語言中,而我用最多的應該在 JavaScript 和 Objective C (code block) 中了。但老實說,我對於 Lambda 其實不怎麼有愛,JavaScript 版的寫法我覺得還好,但 Objective C 的 in place code block 我看了覺得好亂,後來大多數的情況下,我都用 method 回傳 code block 的方式在使用。

既然,Java 8 開始支援 Lambda 表示法,那程式的撰寫上會變成怎樣呢?首先,以排序為例,先回到沒有 Lambda 的 Java 世界,要排序一個 List,要先寫一個客製的 Comparator (下方的 IntegerComparator),然後再建立一個 comparator 物件作為 List.sort() 函式的參數 (LambdaExample 中的 sortWithComparator 函式)。

就這點,很多人覺得 Java 很沒有生產力 (Productivity),不過我個人是還蠻喜歡這種寫法,我喜歡寫很多小而簡單的 class,因為用 JUnit 測試這些 class 也很容易 (小 class 邏輯相對簡單易測),另一個好處是越是小的 class 越是容易重複利用。


如果不想另外寫一個 class,在沒有 Lambda 的 Java 世界中其實還有一種寫法,也就是匿名 class (anonymous class),LambdaExample 中的 sortWithAnonymousClass 函式就是這種寫法,這種寫法讓我想起早期剛開始學 Java 時用 JBuilder 這類的 IDE 拖拉 UI,然後在按鈕上點兩下,IDE 會自動產生一段程式碼,然後引導你到某個位置開始寫程式(嗯...Visual Basic 6 好像也是這樣),IDE 產生出來的程式大多是這類的匿名 class。在學了比較正式的物件導向設計後,我幾乎不再用這種寫法,只有偶而在比較沒有影響整體設計的情況下,會偷懶使用一下。不過這種寫法還是有人覺得沒生產力。

Lambda 出現後,程式變成 LambdaExamplesortWithLambdaExpression 函式所示那樣,確實行數減少不少,也有人認為可讀性提高不少,認為可讀性提高的原因是,程式碼就在那裡,不像過去還需要跳到另外一個 class 才能看到實作。關於可讀性這一點,我覺得只有在 Lambda 內的程式邏輯很簡單才成立,如果邏輯很複雜,把兩個不同邏輯的程式碼放在一起,不僅長度變長,可讀性反而降低,與其這樣還不如抽出來成為一個 class 並給予一個有意義的 class 名稱。至於語法用 (arguments) -> {implementation} 表示,可能是 Objective C 的 code block 看多了,有比剛開始第一次看到 Java Lambda 表示法稍微習慣多了。

Java 8除了這種匿名的 Lambda 表示法,其實也是支援將既有函式當成 Lambda 使用的用法,例如 LambdaExamplesortWithMethodReferencesortWithStaticMethodReference。不知道大家覺得 sortWithLambdaExpressionsortWithMethodReference 兩相比較下,哪個可讀性較高呢?我個人是覺得 sortWithMethodReference 比較高,因為從函式的名稱就可以知道是以升冪的方式排序。我個人在寫 JavaScript 時也是比較喜歡這種寫法。

有人可能會提到 Closure 才是最主要的精神,關於這點,我想留到下一篇在討論,這篇先討論 Lambda 對於可讀性和生產力的影響。就可讀性來說,剛剛已經提過了,如果是簡單的邏輯用 Lambda 包起來,確實有提高一部分的可讀性,但如果邏輯很複雜,混雜在一起我個人是覺得反而降低可讀性。就生產力來說,Lambda 某種程度上可以少寫一些程式碼(組成類別的宣告等最低成本),和剛剛相同,如果邏輯簡單,例如 IntegerComparatorcompare 函式只有一行,那為了這一行所付出的成本是很高的,但如果邏輯複雜,少寫最低成本所產生的生產力提升效益就有限了。

而且生產力不能只看少寫多少行程式,以長遠來看,好測試的程式碼反而能帶來更高的生產力,這一點也是我最近開發 iOS App 時大量使用 method 回傳 code block 的原因,我認為提高可測性所產生的生產力提升效益比直接少寫程式碼來的高很多,畢竟維護程式碼的時間遠比撰寫程式碼的時間來的多很多。看下面的範例,doSomething 可能是一個整合的函式,其中夾雜了一個 Lambda 表示法的邏輯在裡面,為了測這段 Lambda 表示法的邏輯,必須透過測試 doSomething 來完成,但如果是一個單獨的 class 如 IntegerComparator 這樣,可以不用透過測 doSomething 來完成,而是直測 IntegerComparator。或是用 method reference 的方式也很好測。


有人可能覺得這例子不太好,確實要提高可測性的方法還有很多,不過,我認為匿名 Lambda 表示法的可測性是很低的。所以如果真的要使用 Java 8 的 Lambda 表示法,我應該會傾向使用 method reference 的方式,除了可測性外,另一個原因是, method reference 可以根據 OO 的準則,例如 single responsibility principle,將合適的函式放在合適的 class中,然後用 method reference 的方式直接引用作為 Lambda 來使用。如此一來,既可提高可讀性 (函式名稱本身可以提高可讀性)、可維護性 (好測試,好的 OO 設計),也提高了可重複利用的程度 (匿名Lambda無法重複利用,但 method reference 可以)。

53會員
104內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
留言0
查看全部
發表第一個留言支持創作者!
Spirit的沙龍 的其他內容
內容十分精實,一百多頁很薄的一本書,但含了很多有用的資訊,就算不是開發微服務,書中的內容也可以用在很多雲端服務的開發與維運上。中文版唯一可惜的地方,翻譯非常不通順,很多不像中文的句子,會看到好幾個「與」連在一起用,標點符號的用法也有點怪,閱讀的痛苦指數有點高...
3/5高品質微服務
今天的任務是找到獨一無案的方法創造新事物,不只讓未來變得不一樣,而且要更好,所以我們要從 0 到 1。最重要的第一步是自己獨立思考。唯有重新看待世界,像古人首次見到它那樣覺得新鮮古怪,我們才能重新創造,並將更好的未來留給後世。
5/5從 0 到 1
這陣子比較有空可以去天瓏書局晃晃,正好看到這本剛上市不久的書,整體上大多數守則,也是我自己一直在遵循的,是相當不錯的一本總結書。但真的要仔細看每一節的內容,理解每個原則背後的情境與想要改善的問題是什麼。如果只是把每一節的標題拿來使用,很容易就會發現衝突的部分。
5/5程式設計守則
今天完全沒有行程,就只有去機場搭飛機回台灣,飯店的自助式早餐依舊是很豐盛,甚至還有一區是可以自由組裝海鮮丼,我沒裝飯,只拿了幾樣海鮮。飛機是 11:05 起飛,所以,雖然離機場很近,提早兩小時到機場,意味著九點多該到機場了。
行程簡述 天空海盧飯店 -> 小豆島土庄港 -> 四國高松港 -> 栗林公園 -> 金刀比羅宮參道午餐 -> 道後溫泉車站、本館和商店街 -> 彩朝樂
行程簡述 岡山國際飯店 -> 四國高松港 -> 小豆島土庄港 -> 土淵海峽 -> 小豆島國際飯店吃午餐 -> 橄欖公園 -> 寒霞溪 -> 二十四瞳映畫村 -> 便利商店 -> 天空海盧飯店 -> 天使之路 -> 天空海盧飯店晚餐 & 休息
內容十分精實,一百多頁很薄的一本書,但含了很多有用的資訊,就算不是開發微服務,書中的內容也可以用在很多雲端服務的開發與維運上。中文版唯一可惜的地方,翻譯非常不通順,很多不像中文的句子,會看到好幾個「與」連在一起用,標點符號的用法也有點怪,閱讀的痛苦指數有點高...
3/5高品質微服務
今天的任務是找到獨一無案的方法創造新事物,不只讓未來變得不一樣,而且要更好,所以我們要從 0 到 1。最重要的第一步是自己獨立思考。唯有重新看待世界,像古人首次見到它那樣覺得新鮮古怪,我們才能重新創造,並將更好的未來留給後世。
5/5從 0 到 1
這陣子比較有空可以去天瓏書局晃晃,正好看到這本剛上市不久的書,整體上大多數守則,也是我自己一直在遵循的,是相當不錯的一本總結書。但真的要仔細看每一節的內容,理解每個原則背後的情境與想要改善的問題是什麼。如果只是把每一節的標題拿來使用,很容易就會發現衝突的部分。
5/5程式設計守則
今天完全沒有行程,就只有去機場搭飛機回台灣,飯店的自助式早餐依舊是很豐盛,甚至還有一區是可以自由組裝海鮮丼,我沒裝飯,只拿了幾樣海鮮。飛機是 11:05 起飛,所以,雖然離機場很近,提早兩小時到機場,意味著九點多該到機場了。
行程簡述 天空海盧飯店 -> 小豆島土庄港 -> 四國高松港 -> 栗林公園 -> 金刀比羅宮參道午餐 -> 道後溫泉車站、本館和商店街 -> 彩朝樂
行程簡述 岡山國際飯店 -> 四國高松港 -> 小豆島土庄港 -> 土淵海峽 -> 小豆島國際飯店吃午餐 -> 橄欖公園 -> 寒霞溪 -> 二十四瞳映畫村 -> 便利商店 -> 天空海盧飯店 -> 天使之路 -> 天空海盧飯店晚餐 & 休息
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
相信很多初學者學python的原因,不外乎語法簡單、好上手、重點是有很多現成的套件可以玩。那麼,Java呢?有!當然有!而且還多到你不知道該選哪個好! 今天的文章主要示範如何在vscode新建立Java 的maven專案,並且透過maven安裝這些額外的套件(依賴)
Thumbnail
最近配合公司政策換了新電腦,重新回想起從頭建環境的惡夢。本篇文就來記錄一下如何開始踏入Java的第一步,方便起見也使用相對Eclipse、IntelliJ來說輕量不少的VScode作為編輯器。
來到學期2-3的階段,第一個作業就是打造餐廳清單。原本認為經過電影清單的學習經歷之後,對於打造餐廳清單應該也不會太過困難;沒想到我花了2個月的時間才把作業完整交出去。 在寫餐廳清單的初期,第一個碰到的問題就是首頁無法秀出餐廳評分這個選項。我試著參考其他同學的作品也改了版面的設計,卻始終無法出現餐廳評
Thumbnail
位在通化街尾端,靠近六張犁的禾雀咖啡工作室,質樸的感覺是一家適合假日早晨來待上好一會兒的好去處。 主打自家烘培手沖及義式咖啡,最大特色還有自家製的麵包、甜點輕食,最喜歡吃的莫過於他們的鮮奶吐司。曾經住在這裡好長一段時間,週末去搶個一包可以在家裡烤來吃,是相當幸福的感覺。 冰羅馬咖啡則是我喝過最喜歡的
Thumbnail
abstract class = 抽象類別 interface = 介面 抽象類別與介面都無法建立物件。 1. 使用abstract關鍵字來建立抽象類別,interface關鍵字建立介面。 interface只能繼承interface,且可以繼承多個:
Thumbnail
繼承 在Java中,一個類可以由其他類派生。如果你要創建一個類,而且已經存在一個類具有你所需要的屬性或方法,那麼你可以將新創建的類繼承該類。 利用繼承的方法,可以重用已存在類的方法和屬性,而不用重寫這些代碼。被繼承的類稱為超類(super class),派生類稱為子類(subclass)。 繼承的特
Thumbnail
古早的年代想在網頁內埋 Java 還有 Java applet 可以用,在 Java applet 式微後,找來找去比較可以的辦法大概就是編譯成 WebAssembly 了吧! 想要把 Java 編譯成 WebAssembly,有下面三個工具可以選用
Thumbnail
  給對想當Java工程師又興趣的人類,也許你是學生,又或是你正想轉職,我希望你們都不會因為未知而害怕,這條路沒有那麼困難。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
相信很多初學者學python的原因,不外乎語法簡單、好上手、重點是有很多現成的套件可以玩。那麼,Java呢?有!當然有!而且還多到你不知道該選哪個好! 今天的文章主要示範如何在vscode新建立Java 的maven專案,並且透過maven安裝這些額外的套件(依賴)
Thumbnail
最近配合公司政策換了新電腦,重新回想起從頭建環境的惡夢。本篇文就來記錄一下如何開始踏入Java的第一步,方便起見也使用相對Eclipse、IntelliJ來說輕量不少的VScode作為編輯器。
來到學期2-3的階段,第一個作業就是打造餐廳清單。原本認為經過電影清單的學習經歷之後,對於打造餐廳清單應該也不會太過困難;沒想到我花了2個月的時間才把作業完整交出去。 在寫餐廳清單的初期,第一個碰到的問題就是首頁無法秀出餐廳評分這個選項。我試著參考其他同學的作品也改了版面的設計,卻始終無法出現餐廳評
Thumbnail
位在通化街尾端,靠近六張犁的禾雀咖啡工作室,質樸的感覺是一家適合假日早晨來待上好一會兒的好去處。 主打自家烘培手沖及義式咖啡,最大特色還有自家製的麵包、甜點輕食,最喜歡吃的莫過於他們的鮮奶吐司。曾經住在這裡好長一段時間,週末去搶個一包可以在家裡烤來吃,是相當幸福的感覺。 冰羅馬咖啡則是我喝過最喜歡的
Thumbnail
abstract class = 抽象類別 interface = 介面 抽象類別與介面都無法建立物件。 1. 使用abstract關鍵字來建立抽象類別,interface關鍵字建立介面。 interface只能繼承interface,且可以繼承多個:
Thumbnail
繼承 在Java中,一個類可以由其他類派生。如果你要創建一個類,而且已經存在一個類具有你所需要的屬性或方法,那麼你可以將新創建的類繼承該類。 利用繼承的方法,可以重用已存在類的方法和屬性,而不用重寫這些代碼。被繼承的類稱為超類(super class),派生類稱為子類(subclass)。 繼承的特
Thumbnail
古早的年代想在網頁內埋 Java 還有 Java applet 可以用,在 Java applet 式微後,找來找去比較可以的辦法大概就是編譯成 WebAssembly 了吧! 想要把 Java 編譯成 WebAssembly,有下面三個工具可以選用
Thumbnail
  給對想當Java工程師又興趣的人類,也許你是學生,又或是你正想轉職,我希望你們都不會因為未知而害怕,這條路沒有那麼困難。