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

 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. jqgrid 上移下移单元格

    在表格中常常需要调整表格中数据的显示顺序,我用的是jqgrid,实现原理就是将表中的行数保存到数据库中,取数据时按行进行排序 1.上移,下移按钮 <a href="javascript ...

  2. Android的存储方式

    Android常见的四种存储方式: 1. SharePreference 2. File 3. ContentProvider 4. SQLite 第一种: 保存在应用程序私有的文件夹下---- 只有 ...

  3. SpringSecurity 3.2入门(4)登录密码加密

    密码admin 进行MD5 32位加密为21232F297A57A5A743894A0E4A801FC3 增加spring-security.xml文件配置如下 <!-- 认证管理器,配置Spr ...

  4. Scanners-Box:开源扫描器大全 2017-04-22

    Scanners-Box:开源扫描器大全 2017-04-22 Scanners-Box是一个集合github平台上的安全行业从业人员自研开源扫描器的仓库,包括子域名枚举.数据库漏洞扫描.弱口令或信息 ...

  5. oracle OTT 学习

    1.OTT概念 OTT 是 Object Type Translator 的缩写,对象类型转换器.它是用来将数据库中定义的类型(UDT)转换为C结构体类型的工具.借助OTT 可以用C语言调用OCI来访 ...

  6. python的传递实参

    你经常会发现,向函数传递列表很有用,这种列表包含的可能是名字.数字或更复杂的对象(如字典).将列表传递给函数后,函数就能直接访问其内容 1.在函数中修改列表 将列表传递给函数后,函数就可对其进行修改. ...

  7. python中操作列表

    1.遍历列表 可以用for循环遍历打印非常实用 摸板: for 临时变量 in 列表 : print(临时变量) 注意缩进 , 注意冒号 2.创建数值列表 (1)使用range()函数 , 函数的范围 ...

  8. Vector 、ArrayList、LinkedList比较

    这三者都可以随机访问,也就是支持通过索引查找数据. 都是有序(可以实现元素怎么进怎么出) Vector和ArrayList比较 相同之处 1 它们都是List 它们都继承于AbstractList,并 ...

  9. 【代码笔记】Java基础:类的继承(构造器)

    在Java中,创建对象的格式为: 类名 对象名 = new 类名(): 如: 1 JFrame jf = new JFrame(); 一个对象被创建出来时,经常要先做一些事这个对象才能正常使用,也可以 ...

  10. Eclipse中搭建Android开发环境

    一.搭建Android开发环境 准备工作:下载Eclipse.JDK.Android SDK.ADT插件 下载地址:Eclipse:http://www.eclipse.org/downloads/ ...