1. 程式人生 > >jdk8-Predicate相關函數式接口

jdk8-Predicate相關函數式接口

als ram 我不 present sts eno ted 就是 cat

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類型的結果。

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] */

Predicate還有三個原始類型的相關實現,IntPredicate,LongPredicate,DoublePredicate.示例:
        IntPredicate intPredicate=(i)->i>10;
        Boolean b2=intPredicate.test(11);
        System.out.println(b2);
BiPredicate,是兩個參數的斷言實現,示例:
        BiPredicate<Person,Integer> biPredicate=(p,i)->i.equals(p.getAge());
        Boolean b1=biPredicate.test(Person.builder().age(300).build(),300);
        System.out.println(b1);
        /** true*/

 

jdk8-Predicate相關函數式接口