Predicates – Functional-Style Programming

13.6 Predicates

The Predicate<T> interface should be familiar by now, having been used earlier in Example 13.1, Example 13.2, and Example 13.3.

The Predicate<T> interface defines a boolean-valued function in terms of an instance of its type parameter T. From Table 13.5, we see that its functional method test() has the type T -> boolean—that is, it takes an argument of type T and returns a value of type boolean.

Table 13.5 shows all the predicate functional interfaces provided in the java.util.function package. In addition to the three primitive type predicates recognized by their characteristic prefixes, there is also a generic two-arity specialization (BiPredicate<T,U>). Apart from the functional method test() shown for each predicate in Table 13.5, these functional interfaces also define default methods. Neither the primitive type predicates nor the two-arity predicate are subinterfaces of the Predicate<T> interface.

Table 13.5 Predicates

Functional interface (T, U, and R are type parameters)Functional methodDefault methods unless otherwise indicated
Predicate<T>test: T -> booleanand(), or(), negate(), static isEqual(), static not()
IntPredicatetest: int -> booleanand(), or(), negate()
LongPredicatetest: long -> booleanand(), or(), negate()
DoublePredicatetest: double -> booleanand(), or(), negate()
BiPredicate<T, U>test: (T, U) -> booleanand(), or(), negate()

The code below illustrates the removeIf() method from the ArrayList<E> class that requires a predicate and removes all elements from the list that satisfy the predicate. All palindromes are removed from the list denoted by the reference words. The method call element.test(isPalindrome) is invoked on each element of the list by the removeIf() method.

Click here to view code image

Predicate<String> isPalindrome
    = str -> new StringBuilder(str).reverse().toString().equalsIgnoreCase(str);
// Before: [Otto, ADA, Alyah, Bob, HannaH, Java]
words.removeIf(isPalindrome);          // Remove all palindromes.
// After:  [Alyah, Java]

We can equally implement the Predicate<T> functional interface passed as an argument to the ArrayList.removeIf() method using an anonymous class:

Click here to view code image

// Before: [Otto, ADA, Alyah, Bob, HannaH, Java]
words.removeIf(new Predicate<String>() {
  public boolean test(String str) {
    return new StringBuilder(str).reverse().toString().equalsIgnoreCase(str);
  }
});
// After:  [Alyah, Java]

Similarly, the code below removes all words with even length from the list.

Click here to view code image

Predicate<String> isEvenLen = str -> str.length() % 2 == 0;
// Before: [Otto, ADA, Alyah, Bob, HannaH, Java]
words.removeIf(isEvenLen);             // Remove all even length words.
// After:  [ADA, Alyah, Bob]

And in this example, all words starting with “A” are removed from the list.

Click here to view code image

Predicate<String> startsWithA = str -> str.startsWith(“A”);
// Before: [Otto, ADA, Alyah, Bob, HannaH, Java]
words.removeIf(startsWithA);           // Remove all words that start with “A”.
// After:  [Otto, Bob, HannaH, Java]

Leave a Comment