還不瞭解一下 Java 8 Predicate 函式介面

未讀程式碼發表於2021-08-03

同學你好,這裡有一份你的未讀程式碼,等你查收。

這篇文章屬於 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 鏈式程式設計

Predicateor()and()negate() 方法可以隨意組合 Predicate,組合後的判斷邏輯是從左到右,從前到後,順次判斷。

:(數字小於 5 ).and (數字大於 9 ).negate()

:(數字小於 5 )AND (數字大於 9 ) 對於任意數字都得 falsefalse.negate() 取相反 得 true

所以,此判斷邏輯對於任意數字都為 true

示例Predicateor()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}]

BiPredicatePredicate 函式介面一樣,都是返回一個布林型別,唯一不同的是 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);
    }
}

擴充套件閱讀

Java 8 Function 函式介面

Java 8 Predicate 函式介面

Java 8 Consumer 函式介面

Java 8 Supplier 函式介面

Java 8 BiFunction 函式介面

Java 8 BiPredicate 函式介面

Java 8 UnaryOperator 函式介面

參考

BiPredicate (Java Platform SE 8 )

Predicate (Java Platform SE 8 )

Java 8 Predicate 函式介面

這篇文章就到這裡了,我是一個想認認真真寫寫文章的愛折騰的程式猿。

如果想要訂閱,可以關注公眾號 “未讀程式碼 ,或者未讀程式碼部落格,或者加我微信( wn8398)

本文也已經整理到 GitHub.com/niumoo/JavaNotes,歡迎 Star。

相關文章