JAVA8 Predicate接口解析

OK,不廢話,先來簡單看一下Predicate這個接口。


package java.util.function;

import java.util.Objects;

/**
 * @since 1.8
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     */
    boolean test(T t);

    /**
     *
     */
    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);
    }

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


    該接口有一個抽象方法,三個默認方法,一個靜態方法。對於擁有唯一抽象方法的函數式接口,我們可以使用lamda表達式來進行實現。接下來我們就一個個接口的來解析。
首先我們來看一下test方法。

//函數式抽象接口,需要提供實現體,返回boolean類型參數。
   boolean test(T t);

    接下來我們寫個小demo跑一下

public class PredicateTest {

    public static void main(String[] args) {
        Predicate<Integer> predicateInt = x -> x > 10;
        Predicate<String> predicateStr = r -> r.length() > 10;
        System.out.println("第一個Predicate的測試,測試數值是否大於10,結果爲:" + predicateInt.test(11));
        System.out.println("第二個Predicate的測試,測試字符串的長度是否大於10,結果爲:" + predicateStr.test("test"));
    }
}

運行結果:
    第一個Predicate的測試,測試數值是否大於10,結果爲:true
    第二個Predicate的測試,測試字符串的長度是否大於10,結果爲:false

默認方法negate()

// 返回與當前Predicate對象具有相反test抽象接口實現的Predicate對象
    default Predicate<T> negate() {
        return (t) -> !test(t);//返回一個函數式實現
    }
    public static void main(String[] args) {
        Predicate<Integer> predicateInt = x -> x > 10;
        Predicate<String> predicateStr = r -> r.length() > 10;
        System.out.println("第一個Predicate的測試,測試數值是否大於10,結果爲:" + predicateInt.test(11));
        System.out.println("第二個Predicate的測試,測試字符串的長度是否大於10,結果爲:" + predicateStr.test("test"));
        System.out.println("第一個Predicate的【negate方法】測試,測試數值是否大於10,結果爲:" + predicateInt.negate().test(11));
        System.out.println("第二個Predicate的【negate方法】測試,測試字符串的長度是否大於10,結果爲:" + predicateStr.negate().test("test"));
    }
    
結果:
    第一個Predicate的測試,測試數值是否大於10,結果爲:true
    第二個Predicate的測試,測試字符串的長度是否大於10,結果爲:false
    第一個Predicate的【negate方法】測試,測試數值是否大於10,結果爲:false
    第二個Predicate的【negate方法】測試,測試字符串的長度是否大於10,結果爲:true

下面簡單解析一下剩下的默認方法

     /**
     * 返回一個和other的test方法實現進行與操作的Predicate對象
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    
    
     System.out.println("第一個Predicate的【and方法】測試,測試數值是否大於10小於20,結果爲:" + predicateInt.and(x->x<20).test(11));
     結果:true
    
     /**
     * 返回一個和other的test方法實現進行或操作的Predicate對象
     */
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    
    System.out.println("第一個Predicate的【or方法】測試,測試數值是否大於10或小於5,結果爲:" + predicateInt.or(x->x<5).test(4));
    結果:true
    
    /**
     * 若入參不爲空,則返回一個test實現爲判斷是否相等的Predicate對象
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
    System.out.println(Predicate.isEqual(11).test(12));
    結果:false
    

Predicate這個接口的用處就是函數式編程實現,以及在test中實現自己需要的判斷邏輯,代碼量減少了,代碼所展現邏輯更加清晰了。最大的優勢就是作爲方法的函數式入參,可以靈活的修改方法的入參實現,應對變化的需求。
比如:

//過濾年齡超過30歲的人,並添加到result集中。這裏我們如果有新的需求,比如超過20,小於30,啥的,都只要至二級調用filter方法,傳入對應的lambda表達式即可,如:filter(allPersonList, p -> p.getAge() < 30 && p.getAge() > 20)。

public void test() {
    List<Person> ageGreateThanTwenty = filter(allPersonList, p -> p.getAge() >= 30);
    System.out.println(ageGreateThanTwenty);
}
 
private List<Person> filter(List<Person> persons, Predicate<Person> predicate) {
    List<Person> result = Lists.newArrayList();
    for (Person person : persons) {
        if (predicate.test(person)) {
            result.add(person);
        }
    }
    return result;
}

謝謝·

參考:
https://blog.csdn.net/qq_28410283/article/details/80601495
https://www.cnblogs.com/zhandouBlog/p/9383234.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章