Java 8 Predicate 函數(shù)接口

Predicate 函數(shù)接口同之前介紹的 Function 接口一樣,是一個(gè)函數(shù)式接口,它可以接受一個(gè)泛型 <T> 參數(shù),返回值為布爾類型。Predicate 常用于數(shù)據(jù)過濾,如過濾出集合中符合某個(gè)條件的元素。
源碼:Java 8 中函數(shù)接口 Predicate。
package java.util.function;
import java.util.Objects;
@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);
}
}
1. Predicate test
Predicate 函數(shù)接口可以用于判斷一個(gè)參數(shù)是否符合某個(gè)條件。
示例:判斷某個(gè)字符串是否為空。
import java.util.function.Predicate;
public class Java8PredicateTest {
public static void main(String[] args) {
Predicate<String> isEmpty = String::isEmpty;
System.out.println(isEmpty.test(""));
System.out.println(isEmpty.test("www.wdbyte.com"));
}
}
輸出結(jié)果:
true
false
2. Predicate Stream filter
Stream 中的 filter() 方法是通過接收一個(gè) Predicate 函數(shù)接口實(shí)現(xiàn)的。
示例:過濾出集合中,字符串長度為 4 的字符串。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Java8PredicateFilter {
public static void main(String[] args) {
List<String> list = Arrays.asList("java", "node", "www.wdbyte.com");
list = list.stream().filter(str -> str.length() == 4).collect(Collectors.toList());
System.out.println(list);
}
}
輸出結(jié)果:
[java, node]
3. Predicate and
使用 and() 方法,可以讓前后兩個(gè) Predicate 判斷條件一起生效。
示例 1:過濾數(shù)字集合中,數(shù)字大小在 5 至 9 之間的數(shù)字。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Java8PredicateAnd {
public static void main(String[] args) {
List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
Predicate<Integer> greaterThan5 = number -> number > 5;
Predicate<Integer> lessThan9 = number -> number < 9;
Predicate<Integer> filter = greaterThan5.and(lessThan9);
numberList = numberList.stream().filter(filter).collect(Collectors.toList());
System.out.println(numberList);
}
}
結(jié)果輸出:
[6, 7, 8]
示例 2:一個(gè) Predicate 過濾數(shù)字集合中,數(shù)字大小在 5 至 9 之間的數(shù)字。
List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
numberList = numberList.stream().filter(x -> x > 5 && x < 9).collect(Collectors.toList());
System.out.println(numberList);
輸出結(jié)果;
[6, 7, 8]
4. Predicate negate
predicate.negate() 方法會(huì)返回一個(gè)與指定判斷相反的 Predicate。
示例:過濾數(shù)字集合中,數(shù)字不大于 5 的數(shù)字。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Java8PredicateNeagete {
public static void main(String[] args) {
List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
Predicate<Integer> greaterThan5 = number -> number > 5;
numberList = numberList.stream().filter(greaterThan5.negate()).collect(Collectors.toList());
System.out.println(numberList);
}
}
輸出結(jié)果:
[3, 4, 5]
5. Predicate or
示例:過濾數(shù)字集合中,數(shù)字小于等于 5,或者大于等于 9 的數(shù)字。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class Java8PredicateOr {
public static void main(String[] args) {
List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
Predicate<Integer> lessThan5 = number -> number <= 5;
Predicate<Integer> greaterThan8 = number -> number >= 9;
numberList = numberList.stream().filter(lessThan5.or(greaterThan8)).collect(Collectors.toList());
System.out.println(numberList);
}
}
輸出結(jié)果:
[3, 4, 5, 9, 10]
6. Predicate 鏈?zhǔn)骄幊?/span>
Predicate 的 or() ,and(),negate() 方法可以隨意組合 Predicate,組合后的判斷邏輯是從左到右,從前到后,順次判斷。
如:(數(shù)字小于 5 ).and (數(shù)字大于 9 ).negate()。
解:(數(shù)字小于 5 )AND (數(shù)字大于 9 ) 對(duì)于任意數(shù)字都得 false,false.negate() 取相反 得 true。
所以,此判斷邏輯對(duì)于任意數(shù)字都為 true。
示例:Predicate 的 or() ,and(),negate() 方法組合使用。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Java8PredicateChain {
public static void main(String[] args) {
List<Integer> numberList = Arrays.asList(3, 4, 5, 6, 7, 8, 9, 10);
Predicate<Integer> lessThan5 = number -> number <= 5;
Predicate<Integer> greaterThan9 = number -> number >= 9;
// 小于等于 5
System.out.println(filter(numberList, lessThan5));
// 大于 5
System.out.println(filter(numberList, lessThan5.negate()));
// 小于等于 5 或者大于等于 9
System.out.println(filter(numberList, lessThan5.or(greaterThan9)));
// ! (小于等于 5 AND 大于等于 9)
System.out.println(filter(numberList, lessThan5.and(greaterThan9).negate()));
}
public static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
List<T> resultList = new ArrayList<>();
for (T t : list) {
if (predicate.test(t)) {
resultList.add(t);
}
}
return resultList;
}
}
輸出結(jié)果:
[3, 4, 5]
[6, 7, 8, 9, 10]
[3, 4, 5, 9, 10]
[3, 4, 5, 6, 7, 8, 9, 10]
7. Predicate 與對(duì)象
示例:過濾符合某些特征的狗。
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class Java8PredicateObject {
public static void main(String[] args) {
List<Dog> dogList = new ArrayList<>();
dogList.add(new Dog("哈士奇", 1));
dogList.add(new Dog("牧羊犬", 2));
dogList.add(new Dog("柯基", 3));
dogList.add(new Dog("柴犬", 3));
// 找到 3歲的狗
System.out.println(filter(dogList, dog -> dog.getAge().equals(3)));
// 找到哈士奇信息
Predicate<Dog> predicate = dog -> ("哈士奇").equals(dog.getName());
System.out.println(filter(dogList, predicate));
}
public static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
List<T> resultList = new ArrayList<>();
for (T t : list) {
if (predicate.test(t)) { resultList.add(t); }
}
return resultList;
}
}
class Dog {
private String name;
private Integer age;
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
輸出結(jié)果:
[Dog{name='柯基', age=3}, Dog{name='柴犬', age=3}]
[Dog{name='哈士奇', age=1}]
BiPredicate 和 Predicate 函數(shù)接口一樣,都是返回一個(gè)布爾類型,唯一不同的是 Predicate 接受一個(gè)參數(shù),而 BiPredicate 可以接受兩個(gè)不同類型的參數(shù)。
BiPredicate 在 Java 8 中源碼:
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface BiPredicate<T, U> {
boolean test(T t, U u);
default BiPredicate<T, U> and(BiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) && other.test(t, u);
}
default BiPredicate<T, U> negate() {
return (T t, U u) -> !test(t, u);
}
default BiPredicate<T, U> or(BiPredicate<? super T, ? super U> other) {
Objects.requireNonNull(other);
return (T t, U u) -> test(t, u) || other.test(t, u);
}
}