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

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

最新文章

  1. 1、HTML学习 - IT软件人员学习系列文章
  2. Python 前端之JQuery
  3. MyEclipse------文件字符输入,输出流读写信息
  4. virt-XXX
  5. HDU-5532 Almost Sorted Array (LIS)
  6. NodeJS模块
  7. pyinstaller打包第一个wxPython程序HelloWorld
  8. [2013 ACM/ICPC Asia Regional Nanjing Online C][hdu 4750]Count The Pairs(kruskal + 二分)
  9. SINGLETON(单例模式)---(孤独的人)
  10. SSIS如何引用外部DLL
  11. 部署 Graylog 日志系统 - 每天5分钟玩转 Docker 容器技术(92)
  12. c#IO的学习
  13. NDK开发环境安装,CDT安装,Cygwin安装
  14. JVM学习资料
  15. HttpServletResponse简单理解
  16. python---手动实现两个有序列表的合并
  17. Stack的源码分析和应用实例
  18. iOS-Core Animation: 变换
  19. bootstrap datetimepicker日期插件美化
  20. 详解BarTender符号体系特殊选项之“行数”

热门文章

  1. Coursera 机器学习 第7章 Support Vector Machines 学习笔记
  2. js 标签属性与导航
  3. C++程序设计基础(1)程序的编译和执行
  4. 使用mini-define实现前端代码的模块化管理
  5. Paxos、ZAB、RAFT协议
  6. cf567E. President and Roads(最短路计数)
  7. jQuery 添加样式属性的优先级别
  8. C#使用Process类杀死进程,执行命令等
  9. Azure 8月众多新版本公布
  10. .NET部分知识点整理