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
留言分享你的想法!
avatar-img
Spirit的沙龍
55會員
107內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
Spirit的沙龍的其他內容
2024/05/23
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
2024/05/23
本書大多數的內容都以 OO 的概念出發,詳列了許多設計的臭味道,也有大量的例子。個人雖然不會這樣寫程式,但仍是覺得受益良多,至少在 code review 時能更清楚知道該怎麼描述問題。不過,即便不是用 OO 的概念,有些章節還是可以帶來一些想法,用 OO 概念寫程式的人更不該錯過這本好書。
Thumbnail
2024/05/11
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
2024/05/11
實際就業後,會發現收集與分析需求,通常都不是工程師在做,會有另一群人,以非工程的角度收集及分析需求,然後在開發過程中蹦出不同的火花,於是很好奇另一群人的想法是什麼?我不敢說這本書能完全代表另一群人的想法,但確實能夠得到很多有用的思維。推薦給所有的軟體工程師。
Thumbnail
2024/05/09
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
2024/05/09
本書介紹了戰略設計、管理領域複雜度、實際應用領域驅動設計等主題。透過對核心子領域、支持子領域、限界上下文等概念的探討,提供了領域驅動設計的相關知識。這篇文章中還涉及了微服務、事件驅動架構和資料網格等相關主題,提供了設計系統和應用領域驅動設計的指導。
Thumbnail
看更多
你可能也想看
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
此章節旨在引導讀者如何建立Java開發環境,包括安裝JDK、使用命令行工具編寫和運行Java程式,以及如何在Visual Studio Code、IntelliJ IDEA和Eclipse等IDE中設置和使用Java環境。
Thumbnail
此章節旨在引導讀者如何建立Java開發環境,包括安裝JDK、使用命令行工具編寫和運行Java程式,以及如何在Visual Studio Code、IntelliJ IDEA和Eclipse等IDE中設置和使用Java環境。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
如果你曾經撰寫過網頁,那你一定接觸過 JavaScript 無論是在 NodeJs 或是瀏覽器中運行。 但你有沒有想過,我們寫下的 JS 程式碼,這些看似單純的英文和符號,是如何被轉化為機器能夠理解和執行的程式呢? 今天,讓我們一起深入了解其中的核心主角 ——Google 開發的開源 Java
Thumbnail
如果你曾經撰寫過網頁,那你一定接觸過 JavaScript 無論是在 NodeJs 或是瀏覽器中運行。 但你有沒有想過,我們寫下的 JS 程式碼,這些看似單純的英文和符號,是如何被轉化為機器能夠理解和執行的程式呢? 今天,讓我們一起深入了解其中的核心主角 ——Google 開發的開源 Java
Thumbnail
只是 Swift 以 language level 支援 Optional 確實比用 API level 支援的 Java 要簡潔和更具可讀性。Swift 作為一個全新的語言,從一開始的設計就將許多好的語言特性加入,確實讓人驚豔。
Thumbnail
只是 Swift 以 language level 支援 Optional 確實比用 API level 支援的 Java 要簡潔和更具可讀性。Swift 作為一個全新的語言,從一開始的設計就將許多好的語言特性加入,確實讓人驚豔。
Thumbnail
這幾年新出的語言都強打在少寫 code 和提高可讀性,更重要的是能更容易發展出 domain specific language,就這一點 Java 確實有點顯得疲態了。其實文中列的特性大多是一些語法糖衣,但對程式的可讀性和抽象度都能提昇不少,我覺得挺實用也很划算的。
Thumbnail
這幾年新出的語言都強打在少寫 code 和提高可讀性,更重要的是能更容易發展出 domain specific language,就這一點 Java 確實有點顯得疲態了。其實文中列的特性大多是一些語法糖衣,但對程式的可讀性和抽象度都能提昇不少,我覺得挺實用也很划算的。
Thumbnail
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
Thumbnail
Java 8 有了 Base64 編解碼器,方便不少,不過 Apache Commons Codec 提供更多常用的編解碼器,其實是更方便的,但如果你的應用程式中只需要 Base64 編解碼器,在有 Java 8 的環境中確實不需要將 Apache Commons Codec 和專案一起打包。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News