java8学习之Function与BiFunction函数式接口详解
Function接口:
上次中已经使用了Function的apply()方法,但是在这个接口中还存在三个具体实现的方法,如下:

下面来仔细的将剩下的方法学习一下:
compose():
首先来读一下该方法的javadoc的描述:





一路读下来貌似还是有点懵,感觉好绕,下面再来看一下它的具体实现,这样可以就容易理解一些:


说白了,这个方法就是可以组合多个Function,由于该函数最终还是返回的Function,也就是说可以不断的进行多次的compose,了解了方法的说明之后,下面用代码来使用一下它:

先根据咱们读文档上的描述来分析一下:


所以,该程序的结果输出应该是12,下面编译运行一下:

如我们所预期~
andThen():
理解了compose()方法,对于这个方法来说就比较容易理解了,跟compose()恰恰相反,也就是先执行当前函数,然后再执行andThen()方法传参的函数,下面也来读一下它的javaDoc:



下面再来看一下它的具体实现:


下面再来用代码来使用下,其实是比较好理解的:

在运行之前,咱们也来先分析一下结果:


编译运行:

identity():
对于这个接口非常简单,看一下javadoc:

所以这里就不演示了。
BiFuction接口:
对于Function函数式接口而言,只有一个输入参数,那如果想传两个参数呢?这时就可以用BiFunction接口啦,其中的Bi是Bidirectional【双向】的简写,下面看一下它的javadoc:


那怎么使用它呢?试想一下传统方式要实现两数的四则运算会如何去写呢?定义好加减乘除方法,然后分别去调用既可,伪码如下:

那试想一下,是不是对于两数四则运算的场景刚好满足BiFunction的特性,传递两个参数,最后返回一个值,只是说可能具体的行为需要调用者来传递,这不正好是使用Lambda表达式的用途所在么?所以下面用新的写法来实现两数的四则运算:

编译运行:

再一次体现出Lambda表达式传递的是行为,而非值。
另外再来看一下它有默认方法相比Function接口而言有啥区别:

关于为什么在BiFunction中少了compose()方法,这个在之后会进行说明,先看一下具体实现:

由于该方法的javadoc跟Function的andThen说明一样,所以就不细读了,下面直接应用一下:

同样的在运行之前先来分析一下结果:


编译运行:

思考:
①、BiFunction相比Function为啥没有compose()方法,而只有andThen()方法呢?
这里用一个假设法来进行解释,假设BiFunction中有compose()方法,根据Function的compose()方法来看,很明显是需要先执行before函数的,如下:

当然截图的这是Function.compose()方法原型,要是BiFunction也有compose()方法的话,那这个before参数应该也是BiFunction类型的,但是无所谓,问题的重点是:这两个函数最终执行只能返回一个结果,因为一个方法只能有一个返回值,而执行完before函数之后,接着就要应用到当前的函数上了,还是以Function原型举例:

而咱们讨论的是BiFunction,那应用它时是需要两个输入参数的,但是before执行完之后只得到了一个结果,那不互相矛盾了么?所以这就是为啥在BiFunction中木有提供compose()方法的原因啦。
②、 为啥BiFunction的andThen()方法不是BiFunction类型,而是Function类型呢?
这个问题在前面也已经抛出来了,其实如果理解了第一个思考问题那对于这个问题比较容易理解,为啥呢?看下具体实现:

而接着要将这个唯一的返回值要应用到after参数上,因为只有一个参数,所以也只能是用Function,刚好符合Function只有一个参数的语法要求,不可能是用BiFunction。
java8学习之Function与BiFunction函数式接口详解的更多相关文章
- java8学习之BiFunction函数式接口实例演示&Predicate函数式接口详解
BiFunction函数式接口: 在上次中已经对BiFunction接口进行了初步的认识,这里对它进一步学习,这里打算新建一个Person实体,然后新建若干个Person的实例存放在集合中,最后再根据 ...
- [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口
函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...
- java8函数式接口详解、函数接口详解、lambda表达式匿名函数、方法引用使用含义、函数式接口实例、如何定义函数式接口
函数式接口详细定义 函数式接口只有一个抽象方法 由于default方法有一个实现,所以他们不是抽象的. 如果一个接口定义了一个抽象方法,而他恰好覆盖了Object的public方法,仍旧不算做接口的抽 ...
- Java8学习笔记(五)--Stream API详解[转]
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- java8学习之Lambda表达式继续探讨&Function接口详解
对于上次[http://www.cnblogs.com/webor2006/p/8186039.html]已经初步引入的Java8中Stream流的概念,其中使用了map的操作,它需要接受一个Func ...
- Java8内置的四大核心函数式接口
package java_8; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import j ...
- Java8新特性—四大内置函数式接口
Java8新特性--四大内置函数式接口 预备知识 背景 Lambda 的设计者们为了让现有的功能与 Lambda 表达式良好兼容,考虑了很多方法,于是产生了函数接口这个概念. 什么是函数式接口? 函数 ...
- Java8 函数式编程详解
Java8 函数式编程详解 Author:Dorae Date:2017年11月1日23:03:26 转载请注明出处 说起Java8,可能很多人都已经知道其最大的改进,就是引入了Lambda表达式与S ...
- Java8初体验(二)Stream语法详解---符合人的思维模式,数据源--》stream-->干什么事(具体怎么做,就交给Stream)--》聚合
Function.identity()是什么? // 将Stream转换成容器或Map Stream<String> stream = Stream.of("I", & ...
随机推荐
- Microsoft Hackathon 2019 留念
参加今年微软的 Hackathon 是 2019 年 7 月份的事情,但是后来各种各样的事情,考托.考G.网申……就给耽搁了.我本来以为自己的记忆力足够好,几个月以后也能写很多东西,然鹅……现在发现好 ...
- pycharm右键运行unittest、pytest文件
在实际学习过程中,有时候会出现右键运行文件,但没有任何结果的情况.这就是没有使用unittest/pytest 的方式运行. 解决方法: 添加好
- Ubuntu下安装Golong并用Vscode做IDE最有效方法,避免99%的坑 | 轻松学习GO
最详细的教程,避开99%的坑,亲测有效 由于大部分教程都是win版本的,所以专门总结了一个linux版本的,其核心在于环境配置和插件安装,经历本人通宵7小时解决了这个问题,用自己的踩坑帮助大家避坑,希 ...
- python列表的切片与复制
切片,即处理一个完整列表中部分数据. 语法 变量[起始索引:终止索引:步长] 首先创建一个字符串列表 >>> cars = ['toyota', 'honda', 'mazda', ...
- Oracle通过正则表达式分割字符串 REGEXP_SUBSTR
REGEXP_SUBSTR函数格式如下: function REGEXP_SUBSTR(string, pattern, position, occurrence, modifier) string ...
- Ruby Rails学习中:调试信息和 Rails 的三种环境,Users 资源,调试器,Gravatar 头像和侧边栏
注册 一.调试信息和 Rails 环境 现在咱们要实现的用户资料页面是我们这个应用中第一个真正意义上的动态页面.虽然视图的代码不会动态改变, 不过每个用户资料页面显示的内容却是从数据库中读取的.添加动 ...
- MySql 中锁的定义
行级锁,一般是指排它锁,即被锁定行不可进行修改,删除,只可以被其他会话select.行级锁之前需要先加表结构共享锁. 表级锁,一般是指表结构共享锁锁,是不可对该表执行DDL操作,但对DML操作都不限制 ...
- Dom编程-左侧菜单栏设计模型实现
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- SpringBoot 初入门
SpringBoot 初入门 关于介绍什么之类的就不讲了,主要做一下学习记录. 1. 启动方式 IDEA 启动 命令行启动: mvn spring-boot:run 部署到服务器启动: 先进行打包, ...
- linux查询cpu过高原因--java
1. 查询java pid top -c 2. 查询java进程下,线程情况 top -Hp pid(threadIdList) 3. 将10进制线程id转为16进制 printf "%x ...