Java8-6-Predicate接口詳解

上一篇咱們學習了Function和BiFunction函數式接口,本篇繼續瞭解下其餘經常使用的函數式接口。
先來看下Predicate
Predicate函數式接口的主要做用就是提供一個test方法,接受一個參數返回一個布爾類型,Predicate在stream api中進行一些判斷的時候很是經常使用。segmentfault

@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具體應用api

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便可。理解了這種設計思想後,再看上面的例子就很容易理解,自己邏輯並不複雜,分別取出小於五、大於等於五、小於8的元素,最後一個老是返回true的條件意味着打印出集合中全部元素。
除此以外,Predicate還提供了另外三個默認方法和一個靜態方法函數

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方法。而後再下方調用這三個方法,根據傳入的判斷條件觀察輸出結果。ui

最後再來看一下Predicate接口中的惟一一個靜態方法,Java8中接口中除了增長了默認方法也能夠定義靜態方法。this

/**
 * 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方法進行判斷的。咱們看一下具體用法lua

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

這裏會用第一個"test"的equals方法判斷與第二個"test"是否相等,結果true。設計

下一篇code

相關文章
相關標籤/搜索