探索Java8:(三)Predicate接口的使用
上一篇学习了下Function接口的使用,本篇我们学习下另一个实用的函数式接口Predicate。
Predicate的源码跟Function的很像,我们可以对比这两个来分析下。直接上Predicate的源码:
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*/
boolean test(T t);
/**
* Returns a composed predicate that represents a short-circuiting logical
* AND of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code false}, then the {@code other}
* predicate is not evaluated.
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* Returns a predicate that represents the logical negation of this
* predicate.
*/
default Predicate<T> negate() {
return (t) -> !test(t);
}
/**
* Returns a composed predicate that represents a short-circuiting logical
* OR of this predicate and another. When evaluating the composed
* predicate, if this predicate is {@code true}, then the {@code other}
* predicate is not evaluated.
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* Returns a predicate that tests if two arguments are equal according
* to {@link Objects#equals(Object, Object)}.
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
Predicate是个断言式接口其参数是<T,boolean>,也就是给一个参数T,返回boolean类型的结果。跟Function一样,Predicate的具体实现也是根据传入的lambda表达式来决定的。
boolean test(T t);
接下来我们看看Predicate默认实现的三个重要方法and,or和negate
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
这三个方法对应了java的三个连接符号&&、||和!,基本的使用十分简单,我们给一个例子看看:
int[] numbers= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
List<Integer> list=new ArrayList<>();
for(int i:numbers) {
list.add(i);
}
Predicate<Integer> p1=i->i>5;
Predicate<Integer> p2=i->i<20;
Predicate<Integer> p3=i->i%2==0;
List test=list.stream().filter(p1.and(p2).and(p3)).collect(Collectors.toList());
System.out.println(test.toString());
/** print:[6, 8, 10, 12, 14]*/
我们定义了三个断言p1,p2,p3。现在有一个从1~15的list,我们需要过滤这个list。上述的filter是过滤出所有大于5小于20,并且是偶数的列表。
假如突然我们的需求变了,我们现在需要过滤出奇数。那么我不可能直接去改Predicate,因为实际项目中这个条件可能在别的地方也要使用。那么此时我只需要更改filter中Predicate的条件。
List test=list.stream().filter(p1.and(p2).and(p3.negate())).collect(Collectors.toList());
/** print:[7, 9, 11, 13, 15]*/
我们直接对p3这个条件取反就可以实现了。是不是很简单?
isEqual这个方法的返回类型也是Predicate,所以我们也可以把它作为函数式接口进行使用。我们可以当做==操作符来使用。
List test=list.stream()
.filter(p1.and(p2).and(p3.negate()).and(Predicate.isEqual(7)))
.collect(Collectors.toList());
/** print:[7] */
探索Java8:(三)Predicate接口的使用的更多相关文章
- Android艺术开发探索第三章————View的事件体系(下)
Android艺术开发探索第三章----View的事件体系(下) 在这里就能学习到很多,主要还是对View的事件分发做一个体系的了解 一.View的事件分发 上篇大致的说了一下View的基础知识和滑动 ...
- Android艺术开发探索第三章——View的事件体系(上)
Android艺术开发探索第三章----View的事件体系(上) 我们继续来看这本书,因为有点长,所以又分了上下,你在本片中将学习到 View基础知识 什么是View View的位置参数 Motion ...
- [译]Java8的函数式接口
Java8引入了 java.util.function 包,他包含了函数式接口,具体的描述在以下api说明文档中: 函数式接口为lambda表达式和方法引用提供目标类型.每个函数式接口有一个单独的抽象 ...
- [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类
[.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类 本节导读:本节主要介绍通过序列 ...
- Java8新特性——接口的默认方法和类方法
Java8新增了接口的默认方法和类方法: 以前,接口里的方法要求全部是抽象方法,java8以后允许在接口里定义默认方法和类方法: 不同的是: 默认方法可以通过实现接口的类实例化的对象来调用,而类方法只 ...
- VLAN终结及三层子接口
VLAN终结是指trunk口与三层口连接时,三层口将VLAN tag去掉,VLAN终结于三层口中.为了让三层口能终结不同的VLAN,并且让VLAN间互通,引入了三层子接口的概念.假设HOST A与SW ...
- .NET中的三种接口实现方式
摘自:http://www.cnblogs.com/zhangronghua/archive/2009/11/25/1610713.html 一般来说.NET提供了三种不同的接口实现方式,分别为隐式接 ...
- 乐字节-Java8新特性-接口默认方法
总概 JAVA8 已经发布很久,而且毫无疑问,java8是自java5(2004年发布)之后的最重要的版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性. Java8 新特性列表如下: 接 ...
- 操作系统的三个接口 shell gui api
操作系统的三个接口 shell gui api 编程语言是用来告诉操作系统干什么的语言. 编程语言是人机交互语言. 程序.进程:任务集.
随机推荐
- 图片放大_css3
.flash_little_img{position:relative;}.flash_little_img{width:500px;height:333px;border:none; margin: ...
- sql server作业管理查看/进程管理查看命令
一.作业管理 (1) select * from msdb.dbo.sysjobhistory 可以查看作业的历史记录 (2) select * from msdb.dbo.sysjobs 查 ...
- 2F+1模式才是高可用 途牛旅游网 还是通过proxy层
2F+1模式才是高可用 途牛旅游网 还是通过proxy层 f f f f f f f f f
- 12 jmeter性能测试实战--web程序
项目背景 项目:XX网站环境:Windows需求:并发登录的性能测试场景:1s增加2个线程,运行2000次(线程数20,Ramp-Up seconds 10,循环次数100).分别看20.40.60并 ...
- js-jquery-插件开发(一)
jQuery插件开发模式 jQuery插件开发方式主要有三种:1.通过$.extend()来扩展jQuery 主要是在jQuery命名空间或者理解成jQuery身上添加了一个静态方法2.通过$.fn ...
- 系列解读Dropout
本文主要介绍Dropout及延伸下来的一些方法,以便更深入的理解. 想要提高CNN的表达或分类能力,最直接的方法就是采用更深的网络和更多的神经元,即deeper and wider.但是,复杂的网络也 ...
- 5分钟带你入门vuex(vue状态管理)
如果你之前使用过vue.js,你一定知道在vue中各个组件之间传值的痛苦,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新,那么接下来我们就来学习 ...
- [LeetCode] 225. Implement Stack using Queues_Easy tag: Design
Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. po ...
- [LeetCode] 680. Valid Palindrome II_Easy tag: Two Pointers
Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...
- isKindOfClass isMemeberOfClass 的区分
isKindOfClass If you use such constructs in your code, you might think it is alright to modify an ob ...