资讯专栏INFORMATION COLUMN

Java8-6-Predicate接口详解

Joyven / 3241人阅读

摘要:上一篇我们学习了和函数式接口,本篇继续了解下其他常用的函数式接口。方法同样接收一个类型,将传入的条件和当前的条件以或者的关系过滤数据。就是将当前条件取反。而返回的这个函数式接口实例是通过传入的的方法进行判断的。

上一篇我们学习了Function和BiFunction函数式接口,本篇继续了解下其他常用的函数式接口。
先来看下Predicate
Predicate函数式接口的主要作用就是提供一个test方法,接受一个参数返回一个布尔类型,Predicate在stream api中进行一些判断的时候非常常用。

@FunctionalInterface
public interface Predicate {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
}

使用泛型T指定传入的参数类型,我们通过一个根据不同条件取出不同数据的例子来看下Predicate具体应用

public class PredicateTest {
    public static void main(String[] args) {
        List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        PredicateTest predicateTest = new PredicateTest();
        //输出大于5的数字
        List result = predicateTest.conditionFilter(list, integer -> integer > 5);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出大于等于5的数字
        result = predicateTest.conditionFilter(list, integer -> integer >= 5);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出小于8的数字
        result = predicateTest.conditionFilter(list, integer -> integer < 8);
        result.forEach(System.out::println);
        System.out.println("-------");
        //输出所有数字
        result = predicateTest.conditionFilter(list, integer -> true);
        result.forEach(System.out::println);
        System.out.println("-------");
    }
    //高度抽象的方法定义,复用性高
    public List conditionFilter(List list, Predicate predicate){
        return list.stream().filter(predicate).collect(Collectors.toList());
    }
}

我们只定义了一个conditionFilter方法,stream()会将当前list作为源创建一个Stream对象,collect(Collectors.toList())是将最终的结果封装在ArrayList中(这部分会在后续stream学习中详细介绍,这里只关注filter即可),filter方法接收一个Predicate类型参数用于对目标集合进行过滤。里面并没有任何具体的逻辑,提供了一种更高层次的抽象化,我们可以把要处理的数据和具体的逻辑通过参数传递给conditionFilter即可。理解了这种设计思想后,再看上面的例子就很容易理解,本身逻辑并不复杂,分别取出小于5、大于等于5、小于8的元素,最后一个总是返回true的条件意味着打印出集合中所有元素。
除此之外,Predicate还提供了另外三个默认方法和一个静态方法

default Predicate and(Predicate other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}

default Predicate or(Predicate other) {
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}

default Predicate negate() {
    return (t) -> !test(t);
}

static  Predicate isEqual(Object targetRef) {
    return (null == targetRef)
            ? Objects::isNull
            : object -> targetRef.equals(object);
}

and方法接收一个Predicate类型,也就是将传入的条件和当前条件以并且的关系过滤数据。or方法同样接收一个Predicate类型,将传入的条件和当前的条件以或者的关系过滤数据。negate就是将当前条件取反。看下具体使用方式

public List conditionFilterNegate(List list, Predicate predicate){
    return list.stream().filter(predicate.negate()).collect(Collectors.toList());
}

public List conditionFilterAnd(List list, Predicate predicate,Predicate predicate2){
    return list.stream().filter(predicate.and(predicate2)).collect(Collectors.toList());
}

public List conditionFilterOr(List list, Predicate predicate,Predicate predicate2){
    return list.stream().filter(predicate.or(predicate2)).collect(Collectors.toList());
}

//大于5并且是偶数
result = predicateTest.conditionFilterAnd(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//6 8 10
System.out.println("-------");

//大于5或者是偶数
result = predicateTest.conditionFilterOr(list, integer -> integer > 5, integer1 -> integer1 % 2 == 0);
result.forEach(System.out::println);//2 4 6 8 9 10
System.out.println("-------");

//条件取反
result = predicateTest.conditionFilterNegate(list,integer2 -> integer2 > 5);
result.forEach(System.out::println);// 1 2 3 4 5
System.out.println("-------");

我们分别借助Predicate的三个默认方法定义了conditionFilterAnd、conditionFilterOr和conditionFilterNegate方法。然后再下方调用这三个方法,根据传入的判断条件观察输出结果。

最后再来看一下Predicate接口中的唯一一个静态方法,Java8中接口中除了增加了默认方法也可以定义静态方法。

/**
 * Returns a predicate that tests if two arguments are equal according
 * to {@link Objects#equals(Object, Object)}.
 *
 * @param  the type of arguments to the predicate
 * @param targetRef the object reference with which to compare for equality,
 *               which may be {@code null}
 * @return a predicate that tests if two arguments are equal according
 * to {@link Objects#equals(Object, Object)}
 */
static  Predicate isEqual(Object targetRef) {
    return (null == targetRef)
            ? Objects::isNull
            : object -> targetRef.equals(object);
}

isEqual方法返回类型也是Predicate,也就是说通过isEqual方法得到的也是一个用来进行条件判断的函数式接口实例。而返回的这个函数式接口实例是通过传入的targetRef的equals方法进行判断的。我们看一下具体用法

System.out.println(Predicate.isEqual("test").test("test"));//true

这里会用第一个"test"的equals方法判断与第二个"test"是否相等,结果true。

下一篇

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70682.html

相关文章

  • Java8-5-Function函数式接口进阶与默认方法详解

    摘要:函数式接口进阶与默认方法详解上一篇我们快速的借助示例演示了的简单应用,体会到了使用对集合处理的便捷和其与函数式接口密不可分的关系,所以为了更高效的使用,有必要更熟练的掌握函数式接口。 Java8-5-函数式接口进阶与默认方法详解上一篇我们快速的借助示例演示了stream api的简单应用,体会到了使用stream api对集合处理的便捷和其与函数式接口密不可分的关系,所以为了更高效的使...

    Miracle_lihb 评论0 收藏0
  • Collection接口详解

    摘要:接口接口作为集合类的父类接口,位于包下,定义了很多集合操作的方法。今天我希望通过对源码的查阅来对接口有所认识,下面我们直接进入源码分析接口源码可以看出,接口继承接口。 Collection接口 Collection接口作为集合类的父类接口,Collectio位于java.util包下,Collectio定义了很多集合操作的方法。今天我希望通过对源码的查阅来对Collection接口有所...

    IamDLY 评论0 收藏0
  • Java常见集合知识详解

    摘要:集合的种类常见的集合类分如下几个种类详解接口是和接口的父接口,也是集合类除外根接口。接口集合中元素的存放特点是元素有序,同一元素可重复。总结中集合是一个非常重要的知识点,在实际运用中也是常常会使用到。 集合的种类 常见的集合类分如下几个种类: Collection - List - ArrayList - LinkedList - Set - HashSet...

    lewinlee 评论0 收藏0
  • 六大设计原则详解(1)-单一职责原则

    摘要:方法比如一个修改用户名和密码的需求,我们把它写在一个方法里天津市上述代码的方法职责不明确,既有修改用户名又修改地址,不符合单一职责原则。 Android学习资源分享合集(1)-视频资源 简介: 单一职责原则(SRP:Single responsibility principle),它规定一个类应该只有一个发生变化的原因。所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这...

    sihai 评论0 收藏0
  • ES6的Iterator对象详解

    摘要:实现原理创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。具体来说,就是返回一个包含和两个属性的对象。接口部署在对象的属性上可以调用这个属性,就得到遍历器对象。 Iterator实现原理 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。 第一次调用指针对象的next方法,可以将指针指向数据结构的第一...

    KoreyLee 评论0 收藏0

发表评论

0条评论

Joyven

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<