Spring8中lambda表達式的學習(Function接口、BiFunction接口、Consumer接口)


代碼重構,為了確保功能的等效性,梳理代碼時,發現如下代碼:

 1 public  SingleRespTTO fundI(SingleReqTTO request) throws Exception {
 2     return handlerSingleReq((req, logInfo) -> {
 3        
 4         // 業務操作
 5         ....略....
 6     }, request);
 7 }
 8 
 9 public SingleRespTTO handlerSingleReq(BiConsumer<SingleReqTTO, SingleRespTTO> consumer,
10                                           SingleReqTTO request) throws Exception {
11     // 業務操作
12     consumer.accept(request, respTTO);
13         ....略....
14     return respTTO;
15 }
View Code

 

問題:

fundI(SingleReqTTO request)方法實現很簡單:

直接調用handlerSingleReq(BiConsumer<SingleReqTTO, SingleRespTTO> consumer,SingleReqTTO request)方法並返回,而handlerSingleReq的參數1 consumer是個lambda表達式:

(req, logInfo) -> {
    // 業務操作
    ....略....
}

1、lambda表達式的方法參數是啥

這個lambda表達式有2個參數:req, logInfo,這是哪來的?

2、方法執行順序是啥

lambda作為參數,包含有方法體(很明顯還是個內部實現),先執行該lambda的內部邏輯呢還是先執行的handlerSingleReq方法體呢?

 

解析:

lambda的三個概念:Function接口、BiFunction接口、Consumer接口分析

 

問題答案:

 Java8 內置的四大核心函數式接口:

內置的四大核心函數式接口

函數式接口

參數類型 返回類型 用途

Consumer<T>
消費型接口

T

void

對類型為T的對象應用操作,包含方法 :
void accept(T t)

Supplier<T>
供給型接口

T

返回類型為T的對象,包含方法 :
T get()

Function<T, R>
函數型接口

T R

對類型為T的對象應用操作,並返回結果。結果是R類型的對象,包含方法 :
R apply(T t)

Predicate<T>
斷定型接口

T Boolean

確定類型為T的對象是否滿足某約束,並返回boolean 值。包含方法 :
boolean test(T t)

 

 

 

 

 

 

 

 

 

 

 

函數式接口,具體請參考:

https://blog.csdn.net/chenshun123/article/details/78122467

https://www.cnblogs.com/knowledgesea/p/3163725.html

https://blog.csdn.net/qq_28410283/article/details/80618456

https://blog.csdn.net/qq_29848473/article/details/79554472

簡單一句話:只要是@FunctionalInterface 修飾的接口都是函數式接口,就可以通過lambda表達式簡化代碼(lambda最大的優勢就是簡潔的代碼

查看代碼,這里調用的是,查看源碼如下:

 1 @FunctionalInterface
 2 public interface BiConsumer<T, U> {
 3 
 4     /**
 5      * Performs this operation on the given arguments.
 6      *
 7      * @param t the first input argument
 8      * @param u the second input argument
 9      */
10     void accept(T t, U u);
11 
12     /**
13      * Returns a composed {@code BiConsumer} that performs, in sequence, this
14      * operation followed by the {@code after} operation. If performing either
15      * operation throws an exception, it is relayed to the caller of the
16      * composed operation.  If performing this operation throws an exception,
17      * the {@code after} operation will not be performed.
18      *
19      * @param after the operation to perform after this operation
20      * @return a composed {@code BiConsumer} that performs in sequence this
21      * operation followed by the {@code after} operation
22      * @throws NullPointerException if {@code after} is null
23      */
24     default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
25         Objects.requireNonNull(after);
26 
27         return (l, r) -> {
28             accept(l, r);
29             after.accept(l, r);
30         };
31     }
32 }
View Code

解釋:

接口有一個 accept方法,必須自己實現,它接收兩個泛型參數,而另一個方法是默認實現好的方法;

簡單測試下:

 1     public static void main(String[] args) {
 2         BiConsumer<Integer,String> biconsumer = (x,y) -> {
 3             int a = x + 2;
 4             System.out.println(a);// 12
 5             System.out.println("----"+y);// ----我愛你
 6         };
 7         biconsumer.accept(10,"我愛你");
 8 
 9         System.out.println("-----執行andThen()方法--------");
10         BiConsumer<Integer,String> afterBiconsumer = (x,y) -> {
11             int a = x + 8;
12             System.out.println(a);// 18
13             System.out.println("----"+y);// ----哇呀呀
14         };
15         biconsumer.andThen(afterBiconsumer).accept(10,"哇呀呀");
16     }
17 }
View Code

結論:

BiFunction接口暴露的accept方法必須實現,並且是執行的入口(默認實現的andThen()方法,如果調用會執行兩次accept方法,首先執行accept方法,然后執行傳入的BiConsumer引用對象的accept方法方法)

lambda表達式中,BiFunction接口實現體自己不會去執行,它只是實現了accept方法,只有手工去調用它的時候才會執行accept方法體的內容。。。

而且,它接受的2個參數,是調用的時候傳遞過去的,方法體中只是聲明為泛型。。。

 

 

一切都明了:

1、lambda方法參數是啥

handlerSingleReq方法中,consumer.accept(request, respTTO)調用了lambda的的accept方法,參數就在這傳遞

2、方法執行順序是啥

只有調用的時候才執行,handlerSingleReq方法順序執行,consumer.accept(request, respTTO)時執行lambda方法體中的內容...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM