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方法体中的内容...

 

posted @ 2018-12-17 16:32  花花牛  阅读(3290)  评论(0编辑  收藏  举报