iT邦幫忙

2023 iThome 鐵人賽

DAY 2
0
Software Development

Java 17 新登場系列 第 2

Day 2 - Lambda 表達式

  • 分享至 

  • xImage
  •  

Lambda 有著簡短程式碼的含義,不過... Java 這次走到了極簡??

該如何感受才會對妳有感覺?

這要從函數式編程說起... 物件導向的概念可以說是程式界的工業革命,不過物件本身無法很盡善盡美地描述他自己的行為,所以物件導向把行為附加在物件上可以組成形塑我們世界的模型,函數式編程的概念則是把行為動作封裝或視做物件,指派到需要他的地方就能發揮作用的感覺,舉個例子,車手 driver 都會有個方法 - 開車 drive ,法拉利車手或是賓士車手要開這台車需要建立兩個 class 可能繼承 driver 這個母類別,不過 lambda 表示,只要你跟我說他怎麼開的,就決定了他是法拉利還是賓士車手又或是其他車手,就可以開這台車,lambda 只需要"怎麼開的"這個行為就好像是把行為傳遞給 lambda 囉

簡單的例子: Thread

new Thread(new Runnable(){
    @Override
    public void run(){
        System.out.println("I'm running for 2023 ironman competition");
    }
}).start();

// 可以改寫成,變一行
new Thread(()-> System.out.println("I'm running for 2023 ironman competition")).start();

說穿了 lambda 是種簡寫的方式,以往只能傳遞物件參考,而把行為放在類別裡面,現在簡寫到好像是把行為傳遞進去了一樣,()-> System.out.println("I'm running for 2023 ironman competition") 這一行就是 lambda 表達式,最重要的是,這一行的結果會是"物件參考",傳進了 Thread 裡

方法參考

好的,第一關 lambda 表達式是物件,那方法參考就是把既有方法看成是 lambda 表達式
所以演化流程:
物件 <-> lambda 表達式 <-> 方法參考

List<String> strList = Arrays.asList("A","B","C");
// Anonymous class (匿名類別)
strList.forEach(new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.print(s); // ABC
    }
});

// Lambda expression
strList.forEach(s -> System.out.print(s)); // ABC

// Method reference(方法參考)
strList.forEach(System.out::print); // ABC

再強調一次,最後 System.out::print(雙冒號)這個方法表示 lambda 表達式,實際上他回傳了 Consumer 物件,以"A", "B", "C" 作為輪替的輸入,這就是所謂的上下文(只有聰明人看得到?)

今天是 Consumer 介面 accept 不需要回傳值,所以 System.out::print 方法參考也不需要回傳,注意這邊上下文包含回傳值在 lambda 表達式中都必須符合介面的單一方法的輸入輸出,而這個方法動作要放物件方法或是靜態方法(類別方法)皆可,也可以放建構子,不論是複製建構子或是一般建構子或 Var args 建構式皆可

泛函介面

每次看到泛X的出現在書中,都很難理解這一字(泛)的含義,把它翻成英文試試 -- generic 通用的
這個泛函介面是指有 @FunctionInterface annotation 的介面
他會幫忙檢查:

  1. 介面是否只有一個方法
  2. 會在 Javadocs 特別 highlight 出來,表示可以使用 lambda 表達式
  3. 泛函界面可以另外擁有 default 或是 static 方法且都可以有實作在介面裡喔

藉由鐵人賽,我又更拉近與 lambda 的距離了

參考資料:

現代 Java - 輕鬆解決 Java 8 與 9 的難題 (O'REILLY)
https://matthung0807.blogspot.com/2018/08/java-8-method-references.html
https://pdai.tech/md/java/java8/java8-stream.html#%E7%AE%80%E4%BB%8B


上一篇
Day 1 - 從 Java 8 到 17 的 7 個理由
下一篇
Day 3 - java.util.function 套件
系列文
Java 17 新登場8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
Brandy
iT邦新手 3 級 ‧ 2023-09-16 10:01:35

其實functional programming 的概念是比 OO 更早被提出來的。可以參考以下說明能夠更正確認識 Lambda

是純的!函式編程設計

Yes

我要留言

立即登入留言