探索Java8——四大函数

2023-11-05

函数接口,你可以理解为对一段行为的抽象,简单点说可以在方法就是将一段行为作为参数进行传递,这个行为呢,可以是一段代码,也可以是一个方法,那你可以想象在java8之前要将一段方法作为参数传递只能通过匿名内部类来实现,而且代码很难看,也很长,函数接口就是对匿名内部类的优化。
虽然类库中的基本函数接口特别多,但其实总体可以分成四类,就好像阿拉伯数字是无限多的,但总共就10个基本数字一样,理解了这4个,其他的就都明白了。

Function接口

Function的作用是:实现一个”一元函数“,即传入一个值经过函数的计算返回另一个值。在Function中,T代表输入参数,R代表返回的结果。类似于函数 y = f ( x ) y=f(x) y=f(x)

源码解析


  • apply
R apply(T t);

举个例子更好明白 :

public void test(){
    Function<Integer,Integer> test=i->i+1;
    test.apply(5);
}
/** print:6*/

我们用lambda表达式定义了一个行为使得i自增1,我们使用参数5执行apply,最后返回6。

这跟我们以前看待Java的眼光已经不同了,在函数式编程之前我们定义一组操作首先想到的是定义一个方法,然后指定传入参数,返回我们需要的结果。函数式编程的思想是先不去考虑具体的行为,而是先去考虑参数,具体的方法我们可以后续再设置。

public void test(){
    Function<Integer,Integer> test1=i->i+1;
    Function<Integer,Integer> test2=i->i*i;
    System.out.println(calculate(test1,5));
    System.out.println(calculate(test2,5));
}
public static Integer calculate(Function<Integer,Integer> test,Integer number){
    return test.apply(number);
}
/** print:6*/
/** print:25*/

  • compose和andThen

compose和andThen可以解决我们的问题。先看compose的源码:

default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

compose接收一个Function参数,返回时先用传入的逻辑执行apply,然后使用当前Function的apply。

andThen跟compose正相反,先执行当前的逻辑,再执行传入的逻辑。

default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

举个例子:

public void test(){
    Function<Integer,Integer> A=i->i+1;
    Function<Integer,Integer> B=i->i*i;
    System.out.println("F1:"+B.apply(A.apply(5)));
    System.out.println("F1:"+B.compose(A).apply(5));
    System.out.println("F2:"+A.apply(B.apply(5)));
    System.out.println("F2:"+B.andThen(A).apply(5));
}
/** F1:36 */
/** F1:36 */
/** F2:26 */
/** F2:26 */

compose等价于B.apply(A.apply(5)),而andThen等价于A.apply(B.apply(5))。

Consumer 接口

Consumer 接口翻译过来就是消费者,顾名思义,该接口对应的方法类型为接收一个参数,没有返回值,可以通俗的理解成将这个参数’消费掉了’,一般来说使用Consumer接口往往伴随着一些期望状态的改变或者事件的发生,例如最典型的forEach就是使用的Consumer接口,虽然没有任何的返回值,但是却向控制台输出了语句。

    public static void main(String[] args) {
        Consumer<String> printString = s -> System.out.println(s);
        printString.accept("helloWorld!");
        //控制台输出 helloWorld!
    }

Supplier 接口

Supplier 接口翻译过来就是提供者,和上面的消费者相反,该接口对应的方法类型为不接受参数,但是提供一个返回值,通俗的理解为这种接口是无私的奉献者,不仅不要参数,还返回一个值,使用get()方法获得这个返回值

Supplier<String> getInstance = () -> "HelloWorld!";
        System.out.println(getInstance.get());
        // 控偶值台输出 HelloWorld

Predicate 接口

predicate<T,Boolean> 谓语接口,顾名思义,中文中的‘是’与‘不是’是中文语法的谓语,同样的该接口对应的方法为接收一个参数,返回一个Boolean类型值,多用于判断与过滤,当然你可以把他理解成特殊的Funcation<T,R>,但是为了便于区分语义,还是单独的划了一个接口,使用test()方法执行这段行为

public static void main(String[] args) {
        Predicate<Integer> predOdd = integer -> integer % 2 == 1;
        System.out.println(predOdd.test(5));
        //控制台输出 5
    }
    

其他的接口

介绍完正面这四种最基本的接口,剩余的接口就可以很容易的理解了,java8中定义了几十种的函数接口,但是剩下的接口都是上面这几种接口的变种,大多为限制参数类型,数量,下面举几个例子。

类型限制接口
参数类型,例如IntPredicate,LongPredicate, DoublePredicate,这几个接口,都是在基于Predicate接口的,不同的就是他们的泛型类型分别变成了Integer,Long,Double
IntConsumer,LongConsumer, DoubleConsumer比如这几个,对应的就是Consumer<Integer>,Consumer<Long>,Consumer<Double>

数量限制接口
有些接口需要接受两名参数,此类接口的所有名字前面都是附加上Bi,是Binary的缩写,开头也介绍过这个单词了,是二元的意思,例如BiPredicate,BiFcuntion等等,而由于java没有多返回值的设定,所以Bi指的都是参数为两个。

计算 a + b的BiFcuntion如果限制条件为Integer的话 往往要这么写BiFunction<Integer,Integer,Integer> 前2个泛型代表参数,最后一个代表返回值

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

探索Java8——四大函数 的相关文章

随机推荐

  • 【傅里叶级数与傅里叶变换】数学推导——1、基础知识点回顾及[Part1:三角函数的正交性]介绍

    文章内容来自DR CAN关于傅里叶变换的视频 本篇文章提供了一些基础知识点 比如三角函数常用的导数 三角函数换算公式等 文章全部链接 基础知识点 Part1 三角函数系的正交性 Part2 T 2 的周期函数的傅里叶级数展开 Part3 周
  • 42-Golang中的单元测试

    Golang中的单元测试 需求 传统方法 基本介绍 单元测试快速入门总结 综合案例 需求 在工作中 我们会遇到这样的情况 就是去确认一个函数 或者一个模块的结果是否正确 传统方法 在main函数中 调用addUpper函数 看看实际输出的记
  • 内网能ping通telnet 通,不能访问解决

    内网能PING通TELNET通不能访问解决 遇到一个离奇故障 内网 两个主机在同一IP段内 能互相PING通 TELNET对方的WEB服务器端口 通 但用IE访问时不能 显示HTTP400 这明显是客户端系统的问题啊 但如何解决呢 我强烈怀
  • LeetCode 1233. 删除子文件夹(C++)

    思路 1 首先能想到这种判断字符串前缀的题目可以使用前缀树 2 对字符串字典序排序 那么就能满足 一个子文件夹的左边要么是同父文件夹的子文件夹 要么就是他的父文件夹 同时 第一个文件夹一定是父文件夹 那么就可以建立一个父文件夹地址 每次便利
  • vs2019 中文离线安装包下载,类似ISO,不用联网安装vs2019企业版

    vs2019 中文离线安装包下载 类似ISO 不用联网安装vs2019企业版 前言 我们现在微软官方网站下载的安装包一般也就1 2兆 运行这个小安装包的程序时 才真正在网站上下载vs2019 目前的vs2019企业版 专业版 社区版都要20
  • FISCO BCOS 2.9.1 从0部署到简单使用的CRUD接口

    FISCO BCOS 2 9 1 从0部署到简单使用CRUD接口 文章目录 FISCO BCOS 2 9 1 从0部署到简单使用CRUD接口 前言 1 部署fisoc bcos 2 9 1环境 1 1 安装centos依赖 1 2 创建fi
  • Hibernate+spring缓存机制配置

    在applicationContext xml文件中添加以下代码
  • 关于Tp中图片路径的问题

    图片一般放在Public 目录下 在模板文件中引用图片时 src PUBLIC 图片Public 下面的路径 注意在linux下面要区分大小写 windows是不用区分也能识别的 部署服务器上后要严格区分大小写
  • vue之websocket聊天功能实现

    一 首先配置全局websocket 创建webSocket js global js export default ws setWs function newWs this ws newWs main js引入 import webSock
  • iPhone手机使用:微信提示“运行内存不足导致该小程序无法使用“解决方法

    突然发现遇到的一个很诡异的情况 通过分析 解决了 分享一下 如图所示 通过iPhone XR打开微信小程序的时候 微信突然提示 运行内存不足导致该小程序无法使用 然后点击 确定 按钮之后 就关闭了 而且查看手机内存128G的还剩下70G没有
  • org.apache.hive.com.esotericsoftware.kryo.kryoexception: encountered unregistered class id 错误解决办法

    执行hive 任务的时候 有些任务会报下列错误 hive 0 14 版本才会有这个问题 任务重做之后可能又会成功 1 错误信息 hdfs nameservice1 tmp hive dbs 9c29873a 664f 45a4 87f5 a
  • 语音合成方法的主要分类

    语音合成的研究已有多年的历史 现在研究出的语音合成方法的分类 从技术方式讲 可分为波形合成法 参数合成法 和规则合成方法 从合成策略上讲可分为频谱逼近和波形逼近 1 波形合成法 波形合成法一般有两种形式 一种是波形编码合成 它类似于语音编码
  • Redis 6.0 新功能

    1 支持 ACL 1 1 ACL 简介 官网 https redis io topics acl Redis ACL 是访问控制列表 Access Control List 的缩写 该功能允许根据可以执行的命令和可以访问的键来限制某些连接
  • String包含的方法

    public class TestString public static void main String args String s1 new String abc String s2 abc String s3 ABC String
  • 2021-05-28

    什么是散列表 散列表 散列表 Hash table 也叫哈希表 是根据键 Key 而直接访问在内存存储位置的数据结构 也就是说 它通过计算一个关于键值的函数 将所需查询的数据映射到表中一个位置来访问记录 这加快了查找速度 这个映射函数称做散
  • 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾 它使得应用系统 程序 可以以二进制模块的形式灵活地组建起来 比起源码级别的模块化 二进制级别的模块划分使得各模块更加独立 各模块可以分别编译和链接 模块的升级不会引起其它模块和主程序的重新编译 这点对于
  • RabbitMQ--基础--10.2--死信队列

    RabbitMQ 基础 10 2 死信队列 1 死信队列 DLX queue 当消息在一个队列中变成死信之后 它能重新被发送到另一个交换机中 这个交换机就是 死信交换机 绑定 死信交换机 DLX Exchange 的队列就称之为死信队列 死
  • 语句执行顺序对判断语句条件的影响

    对比相同的输出结果下 不同的语句执行顺序对判断语句条件的影响 public class Homework1 public static void main String args 输出1 100偶数 每5个一行 一行中的每个数字之间使用逗号
  • 【深度学习】Loss Functions for Neural Networks for Image Processing

    在目前的深度学习中 业界主流主要还是把调整深度学习网络结构作为主要的工作重心 即使损失函数 loss functions 对整个网络的训练起着十分重要的作用 Nvidia和MIT最近发了一篇论文 loss functions for neu
  • 探索Java8——四大函数

    文章目录 Function接口 源码解析 Consumer 接口 Supplier 接口 Predicate 接口 其他的接口 函数接口 你可以理解为对一段行为的抽象 简单点说可以在方法就是将一段行为作为参数进行传递 这个行为呢 可以是一段