Predicate
TL;DR
Predicate<T>is a built-in functional interface in thejava.util.functionpackage.- It takes one argument and returns a boolean.
- It is primarily used for filtering or evaluating conditions.
- Its abstract method is
boolean test(T t).
Concept
A Predicate represents a simple true/false condition. Instead of writing out if(condition) statements manually inside loops, you can pass a Predicate object to methods (like Stream.filter()) to dynamically apply different rules.
The Predicate interface also has default methods (and(), or(), negate()) that allow you to chain multiple predicates together logically.
Examples
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
// Define a Predicate that checks if a string is longer than 5 chars
Predicate<String> isLongWord = s -> s.length() > 5;
System.out.println(isLongWord.test("Java")); // false
System.out.println(isLongWord.test("Programming")); // true
// Real-world usage: Removing elements from a collection
List<String> names = new ArrayList<>(List.of("Bob", "Alice", "Zack"));
// removeIf() expects a Predicate.
names.removeIf(name -> name.startsWith("B"));
System.out.println(names); // [Alice, Zack]
// --- Chaining Predicates ---
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
// Combines both conditions using logical AND
Predicate<Integer> isPositiveAndEven = isPositive.and(isEven);
System.out.println(isPositiveAndEven.test(4)); // true
}
}
Interview Questions
Q: What is a BiPredicate?
A: While a Predicate<T> takes one argument, a BiPredicate<T, U> takes two arguments and returns a boolean. Its abstract method is boolean test(T t, U u). It is useful when you need to evaluate a condition that requires comparing two separate objects.
Q: How does Predicate.negate() work?
A: negate() is a default method in the Predicate interface that returns a new Predicate representing the logical NOT of the original Predicate. For example, if you have Predicate<String> isEmpty = s -> s.isEmpty();, you can create a new predicate checking for non-empty strings by doing Predicate<String> isNotEmpty = isEmpty.negate();.