函數式接口
先看一下官方定義
Functional interfaces provide target types for lambda expressions and method references.
可以看出函數式接口主要用於lambda表達式,這類接口只定義了唯一的抽象方法的接口(除了隱含的Object對象的公共方法),一開始也稱 SAM 類型接口(Single Abstract Method)。
簡單使用
Listlist = Lists.newArrayList(1,2,3); list.forEach(r -> { System.out.println("re = " + Math.sqrt(r)); });
看一下 foreach
實現,在 Iterable.java
中
default void forEach(Consumer action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
這裡出現的 Consumer
就是一個函數式接口, java8 提供了一些常用的函數式接口
Predicate -- 傳入一個參數,返回一個bool結果, 方法為 boolean test(T t)
Consumer -- 傳入一個參數,無返回值,純消費。 方法為 void accept(T t)
Function -- 傳入一個參數,返回一個結果,方法為 R apply(T t)
Supplier -- 無參數傳入,返回一個結果,方法為 T get()
UnaryOperator -- 一元操作符, 繼承Function,傳入參數的類型和返回類型相同。
BinaryOperator -- 二元操作符, 傳入的兩個參數的類型和返回類型相同, 繼承BiFunction
這裡就不一一列舉了,具體請見 java.util.function 包 都很簡單,不太清楚的自行google
擴展
但是jdk提供的有時候不一定能滿足需求,這個時候就需要我們自定義函數式接口
1.普通的 Function 或者 Consumer 只能就收一個參數,BiFuntion 和 BiConsumer 也只能接受連個參數,參數更多的情況就無法滿足了
以 consumer 為例,先自定義一個接口
@FunctionalInterface public interface TriConsumer{ void accept(T t, U u, W w); default TriConsumerandThen(TriConsumer after) { Objects.requireNonNull(after); return (l, r, w) -> { accept(l, r, w); after.accept(l, r, w); }; } }
函數式接口一般使用 @FunctionalInterface 註解註釋,以申明該接口是一個函數式接口, 這裡提供一個 andThen 方法以支持連續調用
使用方法
TriConsumercOnsumer= (a, b, c) -> { System.out.println(a + b + c); }; consumer.accept(5,6,7);
funtion類似,這裡就不舉例了
2.異常捕獲
FunctionalInterface 提供的接口一般是不拋出異常的,意味著我們在使用的時候需要在方法體內部捕獲異常,這裡定義一種可以拋出異常的接口
@FunctionalInterface public interface InterfaceException{ void apply(T t) throws Exception; }
總結
[f2h0b53ohn ] JDK都出到14了,你有什麼理由不會函數式編程(推薦)已經有249次圍觀