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

 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. 8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07

    1.BIOS中断 我们可以为所有中断类型自定义中断处理过程,包括内部中断.硬件中断和软中断. BIOS中断,又称BIOS功能调用,主要是为了方便地使用最基本的硬件访问功能.通常,为了区分针对同一硬件的 ...

  2. Hadoop 2.7.2 集群搭建(转载)

    http://blog.csdn.net/u010048823/article/details/51913608

  3. bzoj 5217: [Lydsy2017省队十连测]航海舰队

    Description Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格图,其中有些位置是" .",表示这一格是海水,可以通过:有些位置 ...

  4. 深入理解JavaScript系列(12):变量对象(Variable Object)

    介绍 JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么? 原始发布:Dmitry ...

  5. web.config节点

    1.clientCache 源码: <system.webServer> <staticContent> <clientCache cacheControlMode=&q ...

  6. PAT 1066 Root of AVL Tree

    #include <cstdio> #include <cstdlib> class Node { public: Node* L; Node* R; int height; ...

  7. SQL Server 与 ADO.NET 数据类型映射

    SQL Server 数据类型映射 .NET Framework 4.5 SQL Server 和 .NET Framework 基于不同的类型系统. 例如,.NET Framework Decima ...

  8. 模拟Spring框架

    BeanFactory package com.bjsxt.spring; public interface BeanFactory { public Object getBean(String na ...

  9. matlab矩阵

    矩阵的转置用',比如: a = [1,2,3]; b = a'; %b 转置成一个列向量,可以用于矩阵 linspace是Matlab中的一个指令,用于产生指定范围内的指定数量点数,相邻数据跨度相同, ...

  10. /etc/hosts.allow和/etc/hosts.deny详解

    今天遇到一台服务器22端口正常,但是通过ssh连接的问题.排查了防火墙和端口问题,半天没有找出来原因,后来求助大神,终于明白了通过etc目录下hosts.deny和hosts.allow文件可以限制远 ...