zoukankan      html  css  js  c++  java
  • Java8-6-Predicate接口详解

    转自https://segmentfault.com/a/1190000012256677

    Predicate函数式接口的主要作用就是提供一个test方法,接受一个参数返回一个布尔类型,Predicate在stream api中进行一些判断的时候非常常用。

    @FunctionalInterface
    public interface Predicate<T> {
    
        /**
         * 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<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
            PredicateTest predicateTest = new PredicateTest();
            //输出大于5的数字
            List<Integer> 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<Integer> conditionFilter(List<Integer> list, Predicate<Integer> 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)方法和(static)静态方法。在Java 8以前,接口里的方法要求全部是抽象方法。但是静态(static)方法只能通过接口名调用,不可以通过实现类的类名或者实现类的对象调用;默认(default)方法只能通过接口实现类的对象来调用。

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }
    
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

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

    public List<Integer> conditionFilterNegate(List<Integer> list, Predicate<Integer> predicate){
        return list.stream().filter(predicate.negate()).collect(Collectors.toList());
    }
    
    public List<Integer> conditionFilterAnd(List<Integer> list, Predicate<Integer> predicate,Predicate<Integer> predicate2){
        return list.stream().filter(predicate.and(predicate2)).collect(Collectors.toList());
    }
    
    public List<Integer> conditionFilterOr(List<Integer> list, Predicate<Integer> predicate,Predicate<Integer> 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 <T> 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 <T> Predicate<T> 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。

  • 相关阅读:
    [UWP]实现Picker控件
    [UWP]合体姿势不对的HeaderedContentControl
    [UWP]新控件ColorPicker
    [UWP]使用Acrylic(亚克力)
    [UWP]使用Reveal
    [工具]我怎么使用思维导图
    python数据分析师面试题选
    R %operator% 含义
    R中将list类型数据转换成data.frame型
    用R在字符串中提取匹配的部分
  • 原文地址:https://www.cnblogs.com/lijingran/p/8698460.html
Copyright © 2011-2022 走看看