Table of Contents
ToggleJava Predicate Methods
功能接口,使用 Lambda 語法,可當作其他方法的傳入參數或是引用其他方法為實例,常用於過濾條件,傳入 1 個泛型物件參數,結果傳回 boolean,可以使用 and 、 or 組合成鏈式判斷,提高了程式碼的可管理性,有助於分別進行單元測試,Predicate Java Methods 介紹常見的 test 、 and 、 or 等方法,了解 Predicate 的不同操作和方法,本篇增加了範例,並透過單元測試來驗證產出結果。
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- functional
| +- predicate
| +- PredicateMethodsTest.java
單元測試
Predicate Java Methods 提供 test 、 and 、 or 條件或組合成鏈式判斷等操作 Predicate 。
test
建立 Predicate 物件,傳入 1 個參數,判斷是否為真。
@Test
public void test() {
Predicate<String> startsWith = s -> s.startsWith("B");
boolean result = startsWith.test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
result = greaterThan.test(5);
System.out.println(result);
assertTrue(result);
result = greaterThan.test("Ham".length());
System.out.println(result);
assertFalse(result);
}
true
false
true
false
negate
Predicate Java Methods 建立 Predicate 物件,傳入 1 個參數,否定判斷。
@Test
public void negate() {
Predicate<String> startsWith = s -> s.startsWith("B");
boolean result = startsWith.negate().test("Bacon");
System.out.println(result);
assertFalse(result);
result = startsWith.negate().test("Ham");
System.out.println(result);
assertTrue(result);
Predicate<Integer> greaterThan = i -> i > 3;
result = greaterThan.negate().test(5);
System.out.println(result);
assertFalse(result);
result = greaterThan.negate().test("Ham".length());
System.out.println(result);
assertTrue(result);
}
false
true
false
true
and
Predicate Java Methods 建立 2 個 Predicate 物件,各傳入 1 個參數,使用 and 組合判斷是否為真,並傳回 Predicate 是一個短路邏輯運算,其中當第一個 Predicate 為 False 時將不會評估第二個 Predicate 。
@Test
public void and() {
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = startsWith.and(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.and(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = greaterThan.and(lessThan).test(5);
System.out.println(result);
assertTrue(result);
result = greaterThan.and(lessThan).test(6);
System.out.println(result);
assertFalse(result);
}
true
false
true
false
or
Predicate Java Methods 建立 2 個 Predicate 物件,各傳入 1 個參數,使用 or 組合判斷是否為真,並傳回 Predicate 是一個短路邏輯運算,其中當第一個 Predicate 為 True 時將不會評估第二個 Predicate 。
@Test
public void or() {
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = startsWith.or(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.or(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = greaterThan.or(lessThan).test(7);
System.out.println(result);
assertTrue(result);
result = greaterThan.or(lessThan).test(2);
System.out.println(result);
assertTrue(result);
}
true
false
true
true
chaining
Predicate Methods in Java 建立多個 Predicate 物件,各傳入 1 個參數,使用 and 、 or 組合判斷是否為真。
@Test
public void chaining() {
Predicate<String> nonNull = Objects::nonNull;
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = nonNull.and(startsWith).or(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = nonNull.and(startsWith).or(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> intNonNull = Objects::nonNull;
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = intNonNull.and(greaterThan).or(lessThan).test(7);
System.out.println(result);
assertTrue(result);
result = intNonNull.and(greaterThan).or(lessThan).test(2);
System.out.println(result);
assertTrue(result);
}
true
false
true
true
isEqual
Predicate Methods in Java 建立 Predicate 物件,傳入 1 個參數,比較是否相等。
@Test
public void isEqual() {
Predicate<String> isEqual = Predicate.isEqual("Bacon");
boolean result = isEqual.test("Bacon");
System.out.println(result);
assertTrue(result);
result = isEqual.test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> intIsEqual = Predicate.isEqual(6);
result = intIsEqual.test(6);
System.out.println(result);
assertTrue(result);
result = intIsEqual.test(3);
System.out.println(result);
assertFalse(result);
}
true
false
true
false
traditional
Predicate Methods in Java 使用傳統方式,實作 Predicate 接口,判斷是否為真。
public static class LengthGreaterThan<E> implements Predicate<String> {
@Override
public boolean test(String t) {
return t.length() > 3;
}
}
@Test
public void traditional() {
Predicate<String> lengthGreaterThan = new LengthGreaterThan<String>();
Predicate<String> contains = s -> s.contains("o");
boolean result = lengthGreaterThan.and(contains).test("Bacon");
System.out.println(result);
assertTrue(result);
result = lengthGreaterThan.and(contains).test("Ham");
System.out.println(result);
assertFalse(result);
}
true
false
PredicateMethodsTest.java
Predicate Methods in Java 新增單元測試,驗證 Predicate Functions in Java 是否符合預期。
package org.ruoxue.java_147.functional.predicate;
import static org.junit.Assert.*;
import java.util.Objects;
import java.util.function.Predicate;
import org.junit.Test;
public class PredicateMethodsTest {
@Test
public void test() {
Predicate<String> startsWith = s -> s.startsWith("B");
boolean result = startsWith.test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
result = greaterThan.test(5);
System.out.println(result);
assertTrue(result);
result = greaterThan.test("Ham".length());
System.out.println(result);
assertFalse(result);
}
@Test
public void negate() {
Predicate<String> startsWith = s -> s.startsWith("B");
boolean result = startsWith.negate().test("Bacon");
System.out.println(result);
assertFalse(result);
result = startsWith.negate().test("Ham");
System.out.println(result);
assertTrue(result);
Predicate<Integer> greaterThan = i -> i > 3;
result = greaterThan.negate().test(5);
System.out.println(result);
assertFalse(result);
result = greaterThan.negate().test("Ham".length());
System.out.println(result);
assertTrue(result);
}
@Test
public void and() {
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = startsWith.and(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.and(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = greaterThan.and(lessThan).test(5);
System.out.println(result);
assertTrue(result);
result = greaterThan.and(lessThan).test(6);
System.out.println(result);
assertFalse(result);
}
@Test
public void or() {
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = startsWith.or(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = startsWith.or(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = greaterThan.or(lessThan).test(7);
System.out.println(result);
assertTrue(result);
result = greaterThan.or(lessThan).test(2);
System.out.println(result);
assertTrue(result);
}
@Test
public void chaining() {
Predicate<String> nonNull = Objects::nonNull;
Predicate<String> startsWith = s -> s.startsWith("B");
Predicate<String> endsWith = s -> s.endsWith("n");
boolean result = nonNull.and(startsWith).or(endsWith).test("Bacon");
System.out.println(result);
assertTrue(result);
result = nonNull.and(startsWith).or(endsWith).test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> intNonNull = Objects::nonNull;
Predicate<Integer> greaterThan = i -> i > 3;
Predicate<Integer> lessThan = i -> i < 6;
result = intNonNull.and(greaterThan).or(lessThan).test(7);
System.out.println(result);
assertTrue(result);
result = intNonNull.and(greaterThan).or(lessThan).test(2);
System.out.println(result);
assertTrue(result);
}
@Test
public void isEqual() {
Predicate<String> isEqual = Predicate.isEqual("Bacon");
boolean result = isEqual.test("Bacon");
System.out.println(result);
assertTrue(result);
result = isEqual.test("Ham");
System.out.println(result);
assertFalse(result);
Predicate<Integer> intIsEqual = Predicate.isEqual(6);
result = intIsEqual.test(6);
System.out.println(result);
assertTrue(result);
result = intIsEqual.test(3);
System.out.println(result);
assertFalse(result);
}
public static class LengthGreaterThan<E> implements Predicate<String> {
@Override
public boolean test(String t) {
return t.length() > 3;
}
}
@Test
public void traditional() {
Predicate<String> lengthGreaterThan = new LengthGreaterThan<String>();
Predicate<String> contains = s -> s.contains("o");
boolean result = lengthGreaterThan.and(contains).test("Bacon");
System.out.println(result);
assertTrue(result);
result = lengthGreaterThan.and(contains).test("Ham");
System.out.println(result);
assertFalse(result);
}
}
心得分享
Predicate Functions in Java 屬於 java.util.function ,常用於資料過濾,例如:過濾出集合中符合某個條件的元素, 使用 Lambda 表達式能讓程式碼更加簡潔與直接,取代傳統實作接口的方法,減少了很多程式碼,大幅提高可讀性, Predicate Methods in Java 提供更清晰、更易讀且更靈活的方式來組合多個 Predicate 條件,來表示非常複雜的邏輯條件,如: test 、 and 、 or 等,提供了幾種 Predicate 常見範例。