轉自 : Java8的Function接口學習(compose和andThen)
何為Function接口?
在Java8
以后的接口可以有接口方法的默認實現了,如下所示,Function
接口主要代碼及個人整理注釋:
/**
* 代表這一個方法,能夠接受參數,並且返回一個結果
* @since 1.8
*/
@FunctionalInterface
public interface Function<T, R> {
/**
* 將參數賦予給相應方法
*
* @param t
* @return
*/
R apply(T t);
/**
* 先執行參數(即也是一個Function)的,再執行調用者(同樣是一個Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 先執行調用者,再執行參數,和compose相反。
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* 返回當前正在執行的方法
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
由上知道了Function
類的具體代碼,里面有四個方法,分別是apply
,compose
,andThen
,identity
,具體的方法注釋寫在代碼里面了,主要我想在這里敲敲黑板,就是他們的返回值,apply
是R
,也就是代表最終返回結果,其他三個都是返回一個Function
,也就是他們借個是可以進行更多的后層嵌套的,類似於建造者模式去生成類的過程。
具體例子
講的太抽象,這里放出一個具體例子助於理解:
public static void main(String[] args) {
Function<Integer, Integer> times2 = i -> i*2;
Function<Integer, Integer> squared = i -> i*i;
System.out.println(times2.apply(4));
System.out.println(squared.apply(4));
//先4×4然后16×2,先執行apply(4),在times2的apply(16),先執行參數,再執行調用者。
System.out.println(times2.compose(squared).apply(4)); //32
//先4×2,然后8×8,先執行times2的函數,在執行squared的函數。
System.out.println(times2.andThen(squared).apply(4)); //64
System.out.println(Function.identity().compose(squared).apply(4)); //16
}
輸出:
8
16
32
64
16
前兩個輸出比較容易理解,就是把參數值賦值到方法里面,再由apply
返回的結果輸出即可。
主要就是第3,4個的compose
和andThen
**
在compose
里面,先執行squared
的apply(4)
方法,得到16
,然后再把結果給times2
讓它去執行16×2
的方法,得到結果32
。
而andThen
恰恰相反,由英文來理解,先后順序,即先執行times2
的apply
方法得到8
,再把結果執行squared
的平方方法,得到64
。
**
這樣,就能得到最終的結果。
而在最后一個輸出中,雖然有compose
方法,但是前一個的Function.identity
並沒有任何方法,因為identity
僅僅是返回一個方法,所以也就執行了squared
這一個方法而已。
通過上文的分析,大概可以理解Function
這個類了,就是一個方法,有種c++里面函數指針的感覺,一個變量可以指向一個方法,並且可以把兩個方法組合起來使用(使用compose
和andThen
),而可以通過identity
這個靜態方法來獲取當前執行的方法。