日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java8-5-Function函数式接口进阶与默认方法详解

發布時間:2025/3/20 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java8-5-Function函数式接口进阶与默认方法详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java8-5-函數式接口進階與默認方法詳解
上一篇我們快速的借助示例演示了stream api的簡單應用,體會到了使用stream api對集合處理的便捷和其與函數式接口密不可分的關系,所以為了更高效的使用stream api,有必要更熟練的掌握函數式接口。Java8中內置了大量的函數式接口,接下來我們選擇一些比較常用的一起學習下。

Function接口
在之前的文章中,我們簡單介紹過Function接口中apply方法的應用,除了apply這個抽象方法,Function接口中還內置了兩個比較常用的默認方法(接口中增加的有具體實現的方法,擴展了接口功能,子類默認會繼承該實現),看下Function接口源碼

/*** Represents a function that accepts one argument and produces a result.** <p>This is a <a href="package-summary.html">functional interface</a>* whose functional method is {@link #apply(Object)}.** @param <T> the type of the input to the function* @param <R> the type of the result of the function** @since 1.8*/ @FunctionalInterface public interface Function<T, R> {R apply(T t);/*** @return a composed function that first applies the {@code before}* function and then applies this function*/default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {Objects.requireNonNull(before);return (V v) -> apply(before.apply(v));}/*** @return a composed function that first applies this function and then* applies the {@code after} function*/default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}/*** 省略*/ }

Function接口定義中有兩個泛型,按著接口文檔說明第一個泛型是輸入類型,第二泛型是結果類型。
compose方法接收一個Function參數before,該方法說明是返回一個組合的函數,首先會應用before,然后應用當前對象,換句話說就是先執行before對象的apply,再執行當前對象的apply,將兩個執行邏輯串起來。
andThen方法接收一個Function參數after,與compose方法相反,它是先執行當前對象的apply方法,再執行after對象的方法。看一個應用示例

public class FunctionTest {public static void main(String[] args) {FunctionTest functionTest = new FunctionTest();System.out.println(functionTest.compute1(5,i -> i * 2,i -> i * i));//50System.out.println(functionTest.compute2(5,i -> i * 2,i -> i * i));//100}public int compute1(int i, Function<Integer,Integer> after,Function<Integer,Integer> before){return after.compose(before).apply(i);}public int compute2(int i, Function<Integer,Integer> before,Function<Integer,Integer> after){return before.andThen(after).apply(i);} }

定義了compute1和compute2兩個方法,compute1方法第一個參數是要計算的數據,第二個參數是后執行的函數,第一個是先執行的函數,因為輸入輸出都是數字類型,所以泛型都指定為Integer類型,通過after.compose(before);將兩個函數串聯起來然后執行組合后的Funtion方法apply(i)。當調用compute1(5,i -> i 2,i -> i i)時,先平方再乘以2所以結果是50。而compute2方法對兩個Function的調用正好相反,所以結果是100。

BiFunction接口
接下來繼續看下另一個很常用的函數式接口BiFunction

/*** This is the two-arity specialization of {@link Function}.* @param <T> the type of the first argument to the function* @param <U> the type of the second argument to the function* @param <R> the type of the result of the function** @see Function* @since 1.8*/ @FunctionalInterface public interface BiFunction<T, U, R> {/*** Applies this function to the given arguments.** @param t the first function argument* @param u the second function argument* @return the function result*/R apply(T t, U u);/*** Returns a composed function that first applies this function to* its input, and then applies the {@code after} function to the result.* If evaluation of either function throws an exception, it is relayed to* the caller of the composed function.** @param <V> the type of output of the {@code after} function, and of the* composed function* @param after the function to apply after this function is applied* @return a composed function that first applies this function and then* applies the {@code after} function* @throws NullPointerException if after is null*/default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t, U u) -> after.apply(apply(t, u));} }

實際上就是可以有兩個參數的Function,同樣前兩個泛型代表著入參的類型,第三個代表結果類型。

public class BiFunctionTest {public static void main(String[] args) {BiFunctionTest2 biFunctionTest2 = new BiFunctionTest2();System.out.println(biFunctionTest2.compute(4,5,(a,b) -> a * b,a -> a * 2));}public int compute(int a, int b, BiFunction<Integer,Integer,Integer> biFunction,Function<Integer,Integer> function){return biFunction.andThen(function).apply(a,b);} }

看下compute方法,前兩個參數是待計算數據,第三個是一個BiFunction,因為入參和結果都是數組所以三個泛型都定義為Integer。最后一個參數是Function。計算邏輯是先執行BiFunction然后將結果傳給Funciton在計算最后返回結果,所以使用了andThen方法。我們想一下,BiFunction的andThen方法為什么接收的是Function類型的參數而不是BiFunction,答案很簡單,因為BiFunction的apply方法接收兩個參數,但是任何一個方法不可能有兩個返回值,所以也沒辦法放在BiFunction前面執行,這也是為什么BiFunction沒有compose方法的原因。

下一篇

總結

以上是生活随笔為你收集整理的Java8-5-Function函数式接口进阶与默认方法详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。