Java Predicate Methods - Java 147

Java Predicate Methods – Java 147

Java 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 常見範例。

發佈留言