代码重构,为了确保功能的等效性,梳理代码时,发现如下代码:

 public  SingleRespTTO fundI(SingleReqTTO request) throws Exception {
return handlerSingleReq((req, logInfo) -> { // 业务操作
....略....
}, request);
} public SingleRespTTO handlerSingleReq(BiConsumer<SingleReqTTO, SingleRespTTO> consumer,
SingleReqTTO request) throws Exception {
// 业务操作
consumer.accept(request, respTTO);
....略....
return respTTO;
}

问题:

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最大的优势就是简洁的代码

查看代码,这里调用的是,查看源码如下:

 @FunctionalInterface
public interface BiConsumer<T, U> { /**
* Performs this operation on the given arguments.
*
* @param t the first input argument
* @param u the second input argument
*/
void accept(T t, U u); /**
* Returns a composed {@code BiConsumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code BiConsumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after) {
Objects.requireNonNull(after); return (l, r) -> {
accept(l, r);
after.accept(l, r);
};
}
}

解释:

接口有一个 accept方法,必须自己实现,它接收两个泛型参数,而另一个方法是默认实现好的方法;

简单测试下:

     public static void main(String[] args) {
BiConsumer<Integer,String> biconsumer = (x,y) -> {
int a = x + 2;
System.out.println(a);//
System.out.println("----"+y);// ----我爱你
};
biconsumer.accept(10,"我爱你"); System.out.println("-----执行andThen()方法--------");
BiConsumer<Integer,String> afterBiconsumer = (x,y) -> {
int a = x + 8;
System.out.println(a);//
System.out.println("----"+y);// ----哇呀呀
};
biconsumer.andThen(afterBiconsumer).accept(10,"哇呀呀");
}
}

结论:

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

Spring8中lambda表达式的学习(Function接口、BiFunction接口、Consumer接口)的更多相关文章

  1. java 8 中lambda表达式学习

    转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-o ...

  2. Java中Lambda表达式的使用

    简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能.本人建议不要乱用,因 ...

  3. Java中Lambda表达式的使用(转)

    https://www.cnblogs.com/franson-2016/p/5593080.html 简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖" ...

  4. Java中lambda表达式详解

    原文地址:http://blog.laofu.online/2018/04/20/java-lambda/ 为什么使用lambda 在java中我们很容易将一个变量赋值,比如int a =0;int ...

  5. Java8中Lambda表达式的10个例子

    Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...

  6. 死磕Lambda表达式(四):常用的函数式接口

    失去人性,失去很多:失去兽性,失去一切.--<三体> 在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式接口.它们主要 ...

  7. VS编译环境中TBB配置和C++中lambda表达式

    TBB(Thread Building Blocks),线程构建模块,是由Intel公司开发的并行编程开发工具,提供了对Windows,Linux和OSX平台的支持. TBB for Windows ...

  8. Java8 Collections.sort()及Arrays.sort()中Lambda表达式及增强版Comparator的使用

    摘要:本文主要介绍Java8 中Arrays.sort()及Collections.sort()中Lambda表达式及增强版Comparator的使用. 不废话直接上代码 import com.goo ...

  9. java8学习之Lambda表达式继续探讨&Function接口详解

    对于上次[http://www.cnblogs.com/webor2006/p/8186039.html]已经初步引入的Java8中Stream流的概念,其中使用了map的操作,它需要接受一个Func ...

随机推荐

  1. centos系统为php安装memcached扩展

    1. 通过yum安装 yum -y install memcached #安装完成后执行: memcached -h #出现memcached帮助信息说明安装成功 2. 加入启动服务 chkconfi ...

  2. 【卷土重来之C#学习笔记】(一)c#文章导航目录

    [卷土重来之C#学习笔记](一)c#文章导航目录 [卷土重来之C#学习笔记](二)c#编程概述 [卷土重来之C#学习笔记](三)类型.存储.对象 [卷土重来之C#学习笔记](四)类的基本概念 [卷土重 ...

  3. 004 java中的变量

    这篇文章为你搞懂三个问题 什么是变量? 如何使用变量? 变量命名有哪些规范? 变量 计算机的内存类似于人的大脑,电脑使用内存来存储计算所需要的数据. 内存像旅馆一样,不同的房间类型对应不同的数据类型, ...

  4. nyoj 1197——你会加吗?——————【快速幂、分治】

    你会加吗? 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 给出两个整数A和N,计算(A + A^2 + A^3 + …… + A^(N - 1) + A^N)% 6 ...

  5. 4、加载:Loading

    /* ---html----*/ <ion-content> <button (click)="manual()">手动关闭</button> ...

  6. 01.c#中的访问修饰符

    public  公开的 private 私有的,只能在当前类的内部访问 protected  受保护的,只能在当前内的内部以及该类的子类可以访问. internal    可以在同一个程序(项目)集中 ...

  7. C# 用tabcontrol实现窗体类似网页排版的显示

    这里做的比较简陋,可以美化下 把form设置为非顶级控件,直接放在tabcontrol里边,然后实现tabcontrol的拖拽移除tabpage显示form以及添加tabpage mousemove的 ...

  8. 一个基于Ionic3.x cordova的移动APP demo

    项目地址如遇网络不佳,请移步国内镜像加速节点 前端技术: Angular4.x + ionic3.x + cordova 项目运行: git clone git@github.com:EasyTuan ...

  9. vue的一些特殊特性

    一.使用$ref特性获取DOM元素 代码示例如下所示: <!DOCTYPE html> <html lang="en"> <head> < ...

  10. Form表单元素

    Form表单元素 action method input: name value type: text password button radio checkbox file submit reset ...