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