zoukankan      html  css  js  c++  java
  • 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方法体中的内容...

  • 相关阅读:
    内存
    TCP/IP
    安装
    linux常用命令
    linux文本处理三剑客之 grep
    tail命令:显示文件结尾的内容
    less命令:查看文件内容
    head命令:显示文件开头内容
    改进Zhang Suen细化算法的C#实现
    【转】在VS2010上使用C#调用非托管C++生成的DLL文件(图文讲解)
  • 原文地址:https://www.cnblogs.com/huahua035/p/10132289.html
Copyright © 2011-2022 走看看