• 探索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] */
    
  • 相关阅读:
    创建FLASK,同步docker
    FLASK Buleprint
    restful api
    Angular JS
    线程日志
    将项目部署到linux下的docker容器中
    安装和卸载docker
    学习目录总编
    Ansible
    装饰器
  • 原文地址:https://www.cnblogs.com/rever/p/9773743.html
Copyright © 2020-2023  润新知