[六] 函数式接口的复合方法示例 predicate 谓词逻辑运算 Function接口 组合运算 比较器 逆序 比较链
复合的方法
有些函数式接口提供了允许复合的方法
也就是可以将Lambda表达式复合成为一个更加复杂的方法
之前的章节中有说到:
接口中的compose, andThen, and, or, negate 用来组合函数接口而得到更强大的函数接口
另外还有比较器中的reversed thenComparing可以用于组合运算
这几个方法分别位于Function以及Predicate中



方法示例
组合方法 andThen compose
分别计算输入初始值1,2 在四个不同的函数里面的结果
Function<Integer, Integer> f = x -> x + 2;
Function<Integer, Integer> g = x -> x * 4;
Function<Integer, Integer> fAndThenG = f.andThen(g);
for(int i = 1;i<3;i++){
System.out.println(fAndThenG.apply(i));
}
System.out.println("--------------");
Function<Integer, Integer> gAndThenF = g.andThen(f);
for(int i = 1;i<3;i++){
System.out.println(gAndThenF.apply(i));
}
System.out.println("--------------");
Function<Integer, Integer> fComposeG = f.compose(g);
for(int i = 1;i<3;i++){
System.out.println(fComposeG.apply(i));
}
System.out.println("--------------");
Function<Integer, Integer> gComposeF = g.compose(f);
for(int i = 1;i<3;i++){
System.out.println(gComposeF.apply(i));
}
|
初始值为1,2 f (x)= x -> x + 2; g(x) = x -> x * 4; |
|
复合后: f(g(x)) = (x * 4)+2 g(f(x)) = (x+2)*4 |
|
结果分别是 6,10 12,16 |
再看一下打印结果信息

andThen表示 接着进行下一步运算,也就是结果进入到下一个函数中
调用者第一个函数的结果作为被调用者第二个函数的参数
也就是
第二个函数(第一个函数结果) g(f(x)) 的形式
compose 表示组合组成的含义 表示 由谁组成 也就是调用者函数由被调用者函数组成
也就是
第一个函数(第二个函数 结果) f(g(x)) 的形式
显然 对于固定的两个函数 f g
调用与被调用的顺序 和 方法的选择这两者
只能组合出来两种 f(g(x)) 或者 g(f(x))
注意,此处为了更便于表达使用了数学函数的样式展现,但是 Function意味着 输入转换为输出 不要有思维局限性认为就是为了处理数学问题
and, or, negate 与 或 非
与或非 和我们平时理解的概念并无二致 就是执行逻辑运算
and和or方法是按照在表达式链中的位置,从左向右确定优先级的。因此,a.or(b).and(c)可以看作(a || b) && c
class Stu{
private String name;
private String sex;
private Integer age;
public Stu(){
}
public Stu(String name,String sex,Integer age){
this.name = name;
this.sex = sex;
this.age = age;
}
//此处省略了 getter setter方法
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Stu{");
sb.append("name='").append(name).append('\'');
sb.append(", sex='").append(sex).append('\'');
sb.append(", age=").append(age);
sb.append('}');
return sb.toString();
}
}
主函数中的测试代码(省略主函数与测试类)
List<Stu> stuList = new ArrayList(){
{
add(new Stu("Stu1","男",15));
add(new Stu("Stu2","女",18));
add(new Stu("Stu3","男",13));
add(new Stu("Stu4","男",28));
add(new Stu("Stu5","女",58));
add(new Stu("Stu6","女",18));
add(new Stu("Stu7","女",30));
add(new Stu("Stu8","男",6));
}
};
System.out.println(
stuList.stream().filter(i->i.getSex().equals("男")).filter(i->i.getAge().compareTo(18)>0).collect(Collectors.toList())
);
Predicate<Stu> checkSex = i->i.getSex().equals("男");
Predicate<Stu> checkAge = i->i.getAge().compareTo(18)>0;
System.out.println(
stuList.stream().filter(checkSex.and(checkAge)).collect(Collectors.toList())
);
System.out.println(
stuList.stream().filter(checkSex.negate()).collect(Collectors.toList())
);

使用逻辑运算,描述更加清晰,更好理解,更符合声明式编程的思想
可以将多个不同的条件进行组合,灵活性更高
比较器方法
Stream中有 sorted方法

方法的参数正是一个Comparator,提供了
逆序 reversed
和
比较器链thenComparing (还有基本类型特化方法)
List<Stu> stuList = new ArrayList(){
{
add(new Stu("Stu1","男",15));
add(new Stu("Stu2","女",18));
add(new Stu("Stu3","男",13));
add(new Stu("Stu4","男",28));
add(new Stu("Stu5","女",58));
}
};
Comparator<Stu> cName = Comparator.comparing(Stu::getName);
Comparator<Stu> cSex = Comparator.comparing(Stu::getSex);
Comparator<Stu> cAge = Comparator.comparing(Stu::getAge);
System.out.println(
stuList.stream().sorted(cName).collect(Collectors.toList())
);
System.out.println(
stuList.stream().sorted(cName.reversed()).collect(Collectors.toList())
);
System.out.println(
stuList.stream().sorted(cSex).collect(Collectors.toList())
);
System.out.println(
stuList.stream().sorted(cSex.thenComparing(cAge)).collect(Collectors.toList())
);

从结果可以看得出来
第一组按照姓名升序
第二组按照姓名降序
第三组按照性别排序,但是年龄没有排序
第四组按照性别排序,同性别的按照年龄排序
[六] 函数式接口的复合方法示例 predicate 谓词逻辑运算 Function接口 组合运算 比较器 逆序 比较链的更多相关文章
- jdk8系列一、jdk8 Lamda表达式语法、接口的默认方法和静态方法、supplier用法
一.简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性. 在本文中我们将学习这些新特性,并用实际 ...
- Java8新特性——接口的默认方法和类方法
Java8新增了接口的默认方法和类方法: 以前,接口里的方法要求全部是抽象方法,java8以后允许在接口里定义默认方法和类方法: 不同的是: 默认方法可以通过实现接口的类实例化的对象来调用,而类方法只 ...
- 实现继承+接口继承+虚方法+隐藏方法+this/base+抽象类+密封类/方法+修饰符
概念: 在上一节课中学习了如何定义类,用类当做模板来声明我们的数据. 很多类中有相似的数据,比如在一个游戏中,有Boss类,小怪类Enemy,这些类他们有很多相同的属性,也有不同的,这个时候我们可以使 ...
- JMeter接口自动化发包与示例
JMeter接口自动化发包与示例 近期需要完成对于接口的测试,于是了解并简单做了个测试示例,看了看这款江湖上声名远播的强大的软件-Jmeter靠不靠谱. 官网:https://jmeter.apach ...
- 常用的函数式接口_Predicate接口_默认方法and和Predicate接口练习_集合接口筛选
默认方法:and 既然是条件判断,就会存在与.或.非三种常见的逻辑关系.其中将两个Preadicate条件使用"与"逻辑连接起来实现"并且"的效果时,可以使用d ...
- 函数式接口 & lambda表达式 & 方法引用
拉呱: 终于,学习jdk8的新特性了,初体验带给我的感觉真爽,代码精简的不行,可读性也很好,而且,spring5也是把jdk8的融入到血液里,总之一句话吧,说的打趣一点,学的时候自己难受,学完了写出来 ...
- 常用的函数式接口_Prodicate接口_默认方法or&negate和常用的函数式接口_Predicate接口练习_集合信息筛选
常用的函数式接口_Prodicate接口_默认方法or&negate OR package com.yang.Test.PredicateStudy; import java.util.fun ...
- “全栈2019”Java第六十五章:接口与默认方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 常用的函数式接口Function接口和常用的函数式接口Function接口默认方法andThen
常用的函数式接口Function接口 package com.yang.Test.FunctionStudy; import java.util.function.Function; /** * ja ...
随机推荐
- 资源验证(Modified)
Last-Modified : 上次修改时间 配合 If-Modified-Since 或者 If-Unmodified-Since (请求头携带) 对比上次修改时间对资源进行验证 Etag验证 数 ...
- 洛谷p3800:Power收集
考虑朴素的dp: 对于每一行的每一个点 枚举能到的所有点(类似bzoj1648 比这题简单的dp) 期望时间复杂度O(NMT) 显然是超时做法 那么我们发现只有k个点对答案有贡献 考虑对每一个有权值的 ...
- sketch2code 有的叫screenshot to code什么的
先mark一下项目,回头再深究 https://github.com/mzbac/sketch2code https://www.floydhub.com/emilwallner/datasets/h ...
- docker 设计原理
自从上次更新博客截至目前已经8个多月之久,在这大半年里面,我自己经历了好多,换了工作,换了定位,从之前的小运维,到现在负责整个运维部的工作,需要自己协调的事情更多了,最大的成长是可以通过自己的见解对公 ...
- spring事务管理方式,aop
达内12 note unit 09 01 1.spring事务管理 2.spring提供了对事务管理支持 spring采用aop机制完成事务控制 可以实现在不修改原有组件代码情况下实现事务控制功能. ...
- MyEclipse最新版-版本更新说明及下载 - MyEclipse官方中文网
http://www.myeclipsecn.com/learningcenter/myeclipse-update/ [重要更新]MyEclipse 2015正式版发布 [重要更新]MyEclips ...
- NeuChar 平台使用及开发教程(一):开始使用 NeuChar
如果您还不知道什么是 NeuChar,或者我们为什么要做 NeuChar,请看这里. 角色 NeuChar 打通了从开发者到终端用户的完整的上下游链路,了解 NeuChar 之前,先要明确两个角色身份 ...
- js发送post请求,实现下载文件
由于业务需求要下载文件的功能: <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...
- leetcode-数组-子集
一.题目描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], ...
- 高性能网络服务器编程:为什么linux下epoll是最好,Netty要比NIO.2好?
基本的IO编程过程(包括网络IO和文件IO)是,打开文件描述符(windows是handler,java是stream或channel),多路捕获(Multiplexe,即select和poll和ep ...