你的无畏来源于无知。——《三体》

在上一篇文章(传送门)中介绍了Comparator复合,这次我们来介绍一下其他的复合Lambda表达式。

Consumer复合

Consumer接口中,有一个默认方法andThen,它的入参还是Consumer接口的实例。做完上一个Consumer的操作以后,再做当前Consumer的操作,就像工厂的流水线一样,比如:

Consumer<Mask> brand = m -> m.setBrand("3M");
Consumer<Mask> type = m -> m.setType("N95");
Consumer<Mask> price = m -> m.setPrice(19.9);
Consumer<Mask> print = System.out::println; brand.andThen(type)
.andThen(price)
.andThen(print)
.accept(new Mask());

上面的代码分别声明了4个Consumer接口的实例,然后再把它们组装成一个流水线,先把口罩品牌赋值为3M,再把口罩类型赋值为N95,再把口罩价格赋值为19.9,最后把口罩实例打印出来,运行结果如下:

Mask{brand='3M', type='N95', price=19.9}

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

Predicate复合

Predicate接口一共有3个默认方法:negateandor,用它们可以创建更加复杂的Predicate接口实例。

negate方法

negate方法就是做非运算。比如,判断口罩类型是N95:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.test(mask));

运行结果为:

true

那么,使用negate方法以后,就变成了判断口罩类型不是N95:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
System.out.println(isN95.negate().test(mask));

运行结果为:

false

and方法

and方法就是做与运算。比如:

Mask mask = new Mask("Honeywell", "N95",19.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(isN95.and(lessThan20).test(mask));

上面的代码分别声明了2个Predicate接口的实例,分别是判断口罩类型是N95判断口罩价格小于20,使用and方法以后,表示口罩类型是N95 并且 口罩价格小于20,运行结果如下:

true

or方法

or方法就是做或运算。比如:

Mask mask = new Mask("Honeywell", "N95", 21.5);
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(isN95.or(lessThan20).test(mask));

上面的代码分别声明了2个Predicate接口的实例,分别是判断口罩类型是N95判断口罩价格小于20,使用or方法以后,表示口罩类型是N95 或者 口罩价格小于20,运行结果如下:

true

and方法和or方法组合使用

当and方法和or方法组合使用时,优先级是由在Lambda表达式链中的位置决定的,从左到右优先级从高到低,比如:

Mask mask = new Mask("3M", "N95", 21.5);
Predicate<Mask> is3M = m -> "3M".equals(m.getType());
Predicate<Mask> isN95 = m -> "N95".equals(m.getType());
Predicate<Mask> lessThan20 = m -> m.getPrice() < 20.0;
System.out.println(is3M.or(isN95).and(lessThan20).test(mask));

上面的代码分别声明了3个Predicate接口的实例,分别是判断口罩品牌是3M判断口罩类型是N95判断口罩价格小于20,3个Predicate组合以后是is3M.or(isN95).and(lessThan20),根据从左到右优先级从高到低,组合以后的逻辑是(is3M || isN95 ) && lessThan20,所以运行结果如下:

false

欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

Function复合

Function接口一共有2个默认方法:andThencompose,用它们可以创建更加复杂的Function接口实例。

andThen方法

Function接口的andThen方法,和Consumer接口的类似,它的入参还是Function接口的实例。做完上一个Function的操作以后,再做当前Function的操作,比如:

Function<Integer, Integer> plusTwo = x -> x + 2;
Function<Integer, Integer> timesThree = x -> x * 3;
System.out.println(plusTwo.andThen(timesThree).apply(1));
System.out.println(plusTwo.andThen(timesThree).apply(2));
System.out.println(plusTwo.andThen(timesThree).apply(3));

上面的代码分别声明了2个Function接口的实例,先加2,然后再乘以3,也就是(x + 2) * 3,运行结果如下:

9
12
15

compose方法

Function接口的compose方法,和andThen方法相反的,先做当前Function的操作,然后再做上一个Function的操作,比如:

Function<Integer, Integer> plusTwo = x -> x + 2;
Function<Integer, Integer> timesThree = x -> x * 3;
System.out.println(plusTwo.compose(timesThree).apply(1));
System.out.println(plusTwo.compose(timesThree).apply(2));
System.out.println(plusTwo.compose(timesThree).apply(3));

上面的代码分别声明了2个Function接口的实例,先乘以3,然后再加2,也就是(x * 3) + 2,运行结果如下:

5
8
11

《死磕Lambda表达式》系列

微信公众号:万猫学社

微信扫描二维码

获得更多Java技术干货

死磕Lambda表达式(六):Consumer、Predicate、Function复合的更多相关文章

  1. 死磕Lambda表达式(一):初识Lambda

    弱小和无知不是生存的障碍,傲慢才是.--<三体> 什么是Lambda表达式 Lambda表达式是表示可传递匿名函数的一种简洁方式,Lambda表达式没有名称,但是有参数列表.函数主体.返回 ...

  2. 死磕Lambda表达式(二):Lambda的使用

    城市就是森林,每一个男人都是猎手,每一个女人都是陷阱.--<三体> 在哪使用Lambda表达式? 在上一篇文章(传送门)中介绍了Lambda表达式的基本语法,其中的举了一个Lambda表达 ...

  3. 死磕Lambda表达式(三):更简洁的Lambda

    我们都是阴沟里的虫子,但总还是得有人仰望星空.--<三体> 在之前的文章中介绍了Lambda表达式的基本语法和正确使用姿势,这次我来介绍一些Lambda更简洁的用法. 欢迎关注微信公众号: ...

  4. 死磕Lambda表达式(四):常用的函数式接口

    失去人性,失去很多:失去兽性,失去一切.--<三体> 在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式接口.它们主要 ...

  5. 死磕Lambda表达式(五):Comparator复合

    给岁月以文明,而不是给文明以岁月.--<三体> 在上一篇文章(传送门)中介绍了JDK为我们提供的常用函数式接口,JDK不仅提供的这些函数式接口,其中一些接口还为我们提供了实用的默认方法,这 ...

  6. C++ 11 Lambda表达式、auto、function、bind、final、override

    接触了cocos2dx 3.0,就必须得看C++ 11了.有分享过帖子:[转帖]漫话C++0x(四) —- function, bind和lambda.其实最后的Lambda没太怎么看懂. 看不懂没关 ...

  7. 五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》

    系列文章 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强人"锁"难<死磕MySQL系列 三> 四.S 锁与 X 锁的 ...

  8. java8 array、list操作 汇【2】)- (Function,Consumer,Predicate,Supplier)应用

    static class UserT { String name; public UserT(String zm) { this.name=zm; } public String getName() ...

  9. Lambda表达式与Function接口

    Lambda表达式是一个匿名函数.C++ 11和 java 8 相继引入了有关对Lambda表达式的支持. Lambda表达式对于高级语言而言并不是必要的,对于Java而言它的功能和一个简易的接口差不 ...

随机推荐

  1. 谈谈集合.Queue

    之前说到,Java中集合的主要作用就是装盛其他数据和实现常见的数据结构.所以当我们要用到"栈"."队列"."链表"和"数组&quo ...

  2. SQL之开窗函数详解--可代替聚合函数使用

    在没学习开窗函数之前,我们都知道,用了分组之后,查询字段就只能是分组字段和聚合的字段,这带来了极大的不方便,有时我们查询时需要分组,又需要查询不分组的字段,每次都要又到子查询,这样显得sql语句复杂难 ...

  3. Maven pom.xml 添加本地jar包依赖以及打包方法

    Maven项目打包时,如果遇到需要添加本地jar包依赖的时候,可以选择两种方法: 1. 安装到本地仓库 第一种方法比较常规,适用于需要添加的jar包也是由maven项目导出,含有pom文件的时候.只需 ...

  4. dpdk中QSBR具体实现

    目录 dpdk-QSBR实现 初始化 注册与注销 上线与下线 等待静默 附录 参考 dpdk-QSBR实现 dpdk19.01提供了qsbr模式的rcu库,其具体实现在lib/librte_rcu目录 ...

  5. Clipboard.SetText()卡住问题

    调用 Clipboard.SetText(),每次都抛出异常:"CLIPBRD_E_CANT_OPEN" 调查后发现,实际上SetText有成功的将文本复制到Clipboard,但 ...

  6. tensorflow一些API的基本理解

    1.tf.Session self._session = None opts = tf_session.TF_NewSessionOptions(target=self._target, config ...

  7. NIO中的ZeroCopy

    前文提到网络IO可以使用多路复用技术,而文件IO无法使用多路复用,但是文件IO可以通过减少底层数据拷贝的次数来提升性能,而这个减少底层数据拷贝次数的技术,就叫做ZeroCopy. 操作系统层面的Zer ...

  8. JavaScript 模式》读书笔记(4)— 函数1

    从这篇开始,我们会用很长的章节来讨论函数,这个JavaScript中最重要,也是最基本的技能.本章中,我们会区分函数表达式与函数声明,并且还会学习到局部作用域和变量声明提升的工作原理.以及大量对API ...

  9. 记录一次云主机部署openstack的血泪史

    看见这个部署成功的留下了激动的泪水 经过长时间的BUG苦肝终于成功部署成功  部署的环境2vCPU 8GB 阿里云主机,部署成功以后内存占用确实蛮高的 记录这一次踩坑,给后来者避免踩坑时间,个人踩坑踩 ...

  10. 【docker Elasticsearch】Rest风格的分布式开源搜索和分析引擎Elasticsearch初体验

    概述: Elasticsearch 是一个分布式.可扩展.实时的搜索与数据分析引擎. 它能从项目一开始就赋予你的数据以搜索.分析和探索的能力,这是通常没有预料到的. 它存在还因为原始数据如果只是躺在磁 ...