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