同學你好,這裡有一份你的未讀程式碼,等你查收。
這篇文章屬於 Java 8 教程(LTS)系列教程,點選閱讀更多相關文章。
Predicate
函式介面同之前介紹的 Function 介面一樣,是一個函式式介面,它可以接受一個泛型 <T>
引數,返回值為布林型別。Predicate
常用於資料過濾,如過濾出集合中符合某個條件的元素。
原始碼:Java 8 中函式介面 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
函式介面可以用於判斷一個引數是否符合某個條件。
示例:判斷某個字串是否為空。
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"));
}
}
輸出結果:
true
false
2. Predicate Stream filter
Stream
中的 filter()
方法是通過接收一個 Predicate
函式介面實現的。
示例:過濾出集合中,字串長度為 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);
}
}
輸出結果:
[java, node]
3. Predicate and
使用 and()
方法,可以讓前後兩個 Predicate
判斷條件一起生效。
示例 1:過濾數字集合中,數字大小在 5 至 9 之間的數字。
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);
}
}
結果輸出:
[6, 7, 8]
示例 2:一個 Predicate
過濾數字集合中,數字大小在 5 至 9 之間的數字。
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);
輸出結果;
[6, 7, 8]
4. Predicate negate
predicate.negate()
方法會返回一個與指定判斷相反的 Predicate
。
示例:過濾數字集合中,數字不大於 5 的數字。
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); }}
輸出結果:
[3, 4, 5]
5. Predicate or
示例:過濾數字集合中,數字小於等於 5,或者大於等於 9 的數字。
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); }}
輸出結果:
[3, 4, 5, 9, 10]
6. Predicate 鏈式程式設計
Predicate
的 or()
,and()
,negate()
方法可以隨意組合 Predicate
,組合後的判斷邏輯是從左到右,從前到後,順次判斷。
如:(數字小於 5 ).and (數字大於 9 ).negate()。
解:(數字小於 5 )AND (數字大於 9 ) 對於任意數字都得 false
,false.negate()
取相反 得 true
。
所以,此判斷邏輯對於任意數字都為 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; }}
輸出結果:
[3, 4, 5][6, 7, 8, 9, 10][3, 4, 5, 9, 10][3, 4, 5, 6, 7, 8, 9, 10]
7. Predicate 與物件
示例:過濾符合某些特徵的狗。
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 + '}'; }}
輸出結果:
[Dog{name='柯基', age=3}, Dog{name='柴犬', age=3}][Dog{name='哈士奇', age=1}]
BiPredicate
和 Predicate
函式介面一樣,都是返回一個布林型別,唯一不同的是 Predicate
接受一個引數,而 BiPredicate
可以接受兩個不同型別的引數。
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);
}
}
擴充套件閱讀
參考
BiPredicate (Java Platform SE 8 )
Predicate (Java Platform SE 8 )
這篇文章就到這裡了,我是一個想認認真真寫寫文章的愛折騰的程式猿。
如果想要訂閱,可以關注公眾號 “未讀程式碼” ,或者未讀程式碼部落格,或者加我微信( wn8398)。
本文也已經整理到 GitHub.com/niumoo/JavaNotes,歡迎 Star。