函數式程式設計

最近在讀 Clean Architecture 無瑕的程式碼,讀到第六個章節就覺得自己在 Java 的函數式設計不夠熟悉(函數介面),就整理了一下基本應用,希望之後可以應用到底層架構中。
函數介面(Functional Interface)
- 只包含一個抽象方法的介面。
- 它可以擁有多個默認方法(default methods)或靜態方法(static methods),但只能有一個抽象方法。
- 可以標記為 @FunctionalInterface。
- 可以用 lambda 實作,如 Comparator、Function。
1
2
3
4# 實作 Comparator
Comparator comparator = (o1, o2) -> 0;
# 用 default method (返回與當前比較器相反的比較器)
Comparator reversed = comparator.reversed();
Consumer、Function、Predicate 與 Supplier
雖然可以自己定義函數介面,不過 Java 已經有先定義了幾個通用函數介面,需要時可以先考慮通用的,再決定要不要自訂通用函數介面。
Consumer
接受一個引數,處理後不回傳值,就可以使用 Consumer 介面。
因為接受引數但沒有回傳值,等於是消耗了引數,引此叫做 Consumer (這樣很好記)
1 | // Iterable 介面的 forEach 就有用到 |
1 | List<String> list = List.of("This", "is", "functional", "service"); |
另外還有像是 IntConsumer、LongConsumer等等,使用上都一樣。
Function
接受一個引數,處理後回傳計算的結果,就可以使用 Function 介面,因為就像是 y=f(x) 這樣的數學函式,所以就叫做 Function。
1 | // stream 的 map 就有使用到 |
1 | list.stream().map(s -> s.toUpperCase()).forEach(System.out::println); |
和 Consumer 一樣也有 IntFunction、LongFunction 等等。
Predicate
接受一個引數且只回傳一個 boolean 值,就可以使用 Predicate>。
1 | // stream 的 filter 就有使用到 |
1 | list.stream().filter(s -> s.length() > 2).forEach(System.out::println); |
一樣的也有像是 IntPredicate、LongPredicate 等等基本型別可以使用。
Supplier
如果是不接受引數就提供回傳值,就可以使用 Supplier,因為是單純提供所以就叫做 Supplier。
Supplier 應該可以用在初始化或是動態生成的情境。
1 | // Stream.generate 有使用到 |
1 | Stream.generate(() -> Math.random()); |
- Title: 函數式程式設計
- Author: 魯捷
- Created at : 2024-02-10 22:11:12
- Updated at : 2024-02-10 22:15:32
- Link: https://redefine.ohevan.com/2024/02/10/Functional/
- License: This work is licensed under CC BY-NC-SA 4.0.