上一篇学习了下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接口的使用的更多相关文章

  1. Android艺术开发探索第三章————View的事件体系(下)

    Android艺术开发探索第三章----View的事件体系(下) 在这里就能学习到很多,主要还是对View的事件分发做一个体系的了解 一.View的事件分发 上篇大致的说了一下View的基础知识和滑动 ...

  2. Android艺术开发探索第三章——View的事件体系(上)

    Android艺术开发探索第三章----View的事件体系(上) 我们继续来看这本书,因为有点长,所以又分了上下,你在本片中将学习到 View基础知识 什么是View View的位置参数 Motion ...

  3. [译]Java8的函数式接口

    Java8引入了 java.util.function 包,他包含了函数式接口,具体的描述在以下api说明文档中: 函数式接口为lambda表达式和方法引用提供目标类型.每个函数式接口有一个单独的抽象 ...

  4. [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类

    [.net 面向对象程序设计进阶] (11) 序列化(Serialization)(三) 通过接口 IXmlSerializable 实现XML序列化 及 通用XML类 本节导读:本节主要介绍通过序列 ...

  5. Java8新特性——接口的默认方法和类方法

    Java8新增了接口的默认方法和类方法: 以前,接口里的方法要求全部是抽象方法,java8以后允许在接口里定义默认方法和类方法: 不同的是: 默认方法可以通过实现接口的类实例化的对象来调用,而类方法只 ...

  6. VLAN终结及三层子接口

    VLAN终结是指trunk口与三层口连接时,三层口将VLAN tag去掉,VLAN终结于三层口中.为了让三层口能终结不同的VLAN,并且让VLAN间互通,引入了三层子接口的概念.假设HOST A与SW ...

  7. .NET中的三种接口实现方式

    摘自:http://www.cnblogs.com/zhangronghua/archive/2009/11/25/1610713.html 一般来说.NET提供了三种不同的接口实现方式,分别为隐式接 ...

  8. 乐字节-Java8新特性-接口默认方法

    总概 JAVA8 已经发布很久,而且毫无疑问,java8是自java5(2004年发布)之后的最重要的版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性. Java8 新特性列表如下: 接 ...

  9. 操作系统的三个接口 shell gui api

    操作系统的三个接口 shell gui api 编程语言是用来告诉操作系统干什么的语言. 编程语言是人机交互语言. 程序.进程:任务集.

随机推荐

  1. Mergeable Stack 直接list内置函数。(152 - The 18th Zhejiang University Programming Contest Sponsored by TuSimple)

    题意:模拟栈,正常pop,push,多一个merge A B 形象地说就是就是将栈B堆到栈A上. 题解:直接用list 的pop_back,push_back,splice 模拟, 坑:用splice ...

  2. linux:正则表达式grep命令

    基本语法一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列符合某个句法规则的字符串. 一.选择:| |   竖直分隔符表示选择,例如"boy|girl"可 ...

  3. Elasticsearch 基础理论 & 配置调优

    一.简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为 ...

  4. CentOS 6 网络设置

    系统配置: 系统硬件:vmware workstation 系统版本:Centos-6.6-x86_64 路由器网关:192.168.1.1 linux系统网络设置须知: 1.主机所有网卡信息配置文件 ...

  5. RSA加密常用的填充方式 以及 常见错误

    一.RSA加密常用的填充方式 1.RSA_PKCS1_PADDING 输入:比 RSA modulus 短至少11个字节.如果输入的明文过长,必须切割,然后填充 输出:和modulus一样长 根据这个 ...

  6. mysql 连接查询 join

    本文用到的表 CREATE TABLE `cls` ( `cls_id` ) NOT NULL AUTO_INCREMENT, `name` ) NOT NULL, PRIMARY KEY (`cls ...

  7. python对象反射和函数反射

    python的对象反射功能,经常在编程时使用.相比较其它的编程语言使用非常方便.反射就是用字符串来操作对象或者类,模块中的成员. 一.对象的反射 反射功能的实现,由这4个内置函数来实现(hasattr ...

  8. poj2063 Investment

    http://poj.org/problem?id=2063 首先总结一下:总的来说通过这题我深深感觉到了自己的不足,比赛时思维很受限,...面对超时,没有想到好的解决方案. 题意:给出初始资金,还有 ...

  9. Qt addStretch()详解

    addStretch函数,是在布局的时候用到. 函数原型: void QBoxLayout::addStretch ( int stretch = 0 ) 作用:平均分配Layout 比如: QVBo ...

  10. webapi 返回json及route设置

    1.返回json 修改App_Start/webapiconfig public static void Register(HttpConfiguration config) { // Web API ...