函數式程式設計

魯捷 Lv1

最近在讀 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
2
3
4
5
6
7
// Iterable 介面的 forEach 就有用到
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
1
2
3
List<String> list = List.of("This", "is", "functional", "service");
list.forEach(x -> System.out.println(String.join(" ", list)));

另外還有像是 IntConsumer、LongConsumer等等,使用上都一樣。

Function

接受一個引數,處理後回傳計算的結果,就可以使用 Function 介面,因為就像是 y=f(x) 這樣的數學函式,所以就叫做 Function。

1
2
// stream 的 map 就有使用到
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
1
list.stream().map(s -> s.toUpperCase()).forEach(System.out::println);

和 Consumer 一樣也有 IntFunction、LongFunction 等等。

Predicate

接受一個引數且只回傳一個 boolean 值,就可以使用 Predicate>。

1
2
// stream 的 filter 就有使用到
Stream<T> filter(Predicate<? super T> predicate);
1
list.stream().filter(s -> s.length() > 2).forEach(System.out::println);

一樣的也有像是 IntPredicate、LongPredicate 等等基本型別可以使用。

Supplier

如果是不接受引數就提供回傳值,就可以使用 Supplier,因為是單純提供所以就叫做 Supplier。
Supplier 應該可以用在初始化或是動態生成的情境。

1
2
3
4
5
6
// Stream.generate 有使用到
public static<T> Stream<T> generate(Supplier<? extends T> s) {
Objects.requireNonNull(s);
return StreamSupport.stream(
new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
}
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.