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 可以)。

avatar-img
53會員
104內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
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
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
本章節主要介紹Java語言中的函數(也稱為方法)的使用,包括函數的基本結構、函數表達式(Lambda表達式)、箭頭函數、匿名函數的使用,以及如何呼叫函數、如何使用函數參數和函數的返回值等內容。通過學習本章節,讀者將能夠熟練掌握Java語言中的函數相關知識,並能夠在實際編程中靈活運用。
Thumbnail
此章節旨在引導讀者如何建立Java開發環境,包括安裝JDK、使用命令行工具編寫和運行Java程式,以及如何在Visual Studio Code、IntelliJ IDEA和Eclipse等IDE中設置和使用Java環境。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
親愛的 Java 開發者和愛好者們,您是否對於 Java 的魅力充滿好奇?是否有著一個關於 Java 的獨特見解或創新想法?現在是您展現才華的時刻了! 我們誠摯地邀請您參與我們的 Java 投稿活動,分享您的專業知識、經驗和見解。無論您是一位有著多年 Java 開發經驗的專家,還是一位剛剛踏入
Thumbnail
如果你曾經撰寫過網頁,那你一定接觸過 JavaScript 無論是在 NodeJs 或是瀏覽器中運行。 但你有沒有想過,我們寫下的 JS 程式碼,這些看似單純的英文和符號,是如何被轉化為機器能夠理解和執行的程式呢? 今天,讓我們一起深入了解其中的核心主角 ——Google 開發的開源 Java
前言: 一直想要把自己的學習筆記整理整理,至少在寫下筆記的時候,也能釐清觀念。 結果拖延到現在,終於要提筆了,不知道能堅持多久(???)。
Thumbnail
本章節的目的是介紹Java中的套件使用,包括如何引用第三方套件和自定義模組,如何創建和使用自定義套件,以及介紹一些常見的Java標準庫套件。這些內容將幫助讀者更好地理解和使用Java的套件系統。
Thumbnail
本章節主要介紹Java語言中的函數(也稱為方法)的使用,包括函數的基本結構、函數表達式(Lambda表達式)、箭頭函數、匿名函數的使用,以及如何呼叫函數、如何使用函數參數和函數的返回值等內容。通過學習本章節,讀者將能夠熟練掌握Java語言中的函數相關知識,並能夠在實際編程中靈活運用。
Thumbnail
此章節旨在引導讀者如何建立Java開發環境,包括安裝JDK、使用命令行工具編寫和運行Java程式,以及如何在Visual Studio Code、IntelliJ IDEA和Eclipse等IDE中設置和使用Java環境。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
親愛的 Java 開發者和愛好者們,您是否對於 Java 的魅力充滿好奇?是否有著一個關於 Java 的獨特見解或創新想法?現在是您展現才華的時刻了! 我們誠摯地邀請您參與我們的 Java 投稿活動,分享您的專業知識、經驗和見解。無論您是一位有著多年 Java 開發經驗的專家,還是一位剛剛踏入
Thumbnail
如果你曾經撰寫過網頁,那你一定接觸過 JavaScript 無論是在 NodeJs 或是瀏覽器中運行。 但你有沒有想過,我們寫下的 JS 程式碼,這些看似單純的英文和符號,是如何被轉化為機器能夠理解和執行的程式呢? 今天,讓我們一起深入了解其中的核心主角 ——Google 開發的開源 Java
前言: 一直想要把自己的學習筆記整理整理,至少在寫下筆記的時候,也能釐清觀念。 結果拖延到現在,終於要提筆了,不知道能堅持多久(???)。