Functional Interfaces Review — Predicate
The Predicate interface in Java is a functional interface that represents a single argument function that returns a boolean value. It is part of the java.util.function package and is commonly used for filtering or matching purposes. Here’s everything you need to know about the Predicate interface, along with examples:
Definition
The Predicate interface is defined as follows:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: targetRef::equals;
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
}Methods
- test(T t): This is the single abstract method of the
Predicateinterface. It evaluates the predicate on the given argument and returns a boolean value. - and(Predicate<? super T> other): This is a default method that returns a composed predicate that represents a short-circuiting logical AND of this predicate and another.
- or(Predicate<? super T> other): This is a default method that returns a composed predicate that represents a short-circuiting logical OR of this predicate and another.
- negate(): This is a default method that returns a predicate that represents the logical negation of this predicate.
- isEqual(Object targetRef): This is a static method that returns a predicate that tests if two arguments are equal according to
Objects.equals(Object, Object).
Key Points
- Since
Predicateis a functional interface, it can be implemented using lambda expressions or method references. Predicateis often used for filtering collections or streams based on a condition.
Usage Examples
Basic Example
Here’s a simple example of how to use the Predicate interface:
import java.util.function.Predicate;Get Full Stack Developer’s stories in your inbox
Join Medium for free to get updates from this writer.
public class PredicateExample {
public static void main(String[] args) {
// Define a Predicate that checks if a number is greater than 10
Predicate<Integer> isGreaterThanTen = n -> n > 10;
// Use the Predicate
System.out.println(isGreaterThanTen.test(15)); // true
System.out.println(isGreaterThanTen.test(5)); // false
}
}
Chaining Predicates
You can chain multiple Predicate instances using the and, or, and negate methods:
import java.util.function.Predicate;
public class PredicateChainingExample {
public static void main(String[] args) {
// Define two Predicates
Predicate<String> isNotEmpty = s -> s != null && !s.isEmpty();
Predicate<String> isLongerThanFive = s -> s.length() > 5;
// Chain the Predicates
Predicate<String> combinedPredicate = isNotEmpty.and(isLongerThanFive);
// Use the combined Predicate
System.out.println(combinedPredicate.test("Hello, World!")); // true
System.out.println(combinedPredicate.test("Hi")); // false
}
}Using Method References
You can also use method references with Predicate:
import java.util.function.Predicate;
import java.util.List;
public class MethodReferenceExample {
public static void main(String[] args) {
// Define a Predicate using a method reference
Predicate<String> isEmpty = String::isEmpty;
// Use the Predicate with a List
List<String> words = List.of("Apple", "", "Banana");
words.stream()
.filter(isEmpty.negate())
.forEach(System.out::println); // Apple Banana
}
}Using Predicate with Collections
You can use Predicate to filter collections:
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ListPredicateExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Define a Predicate that checks if a number is even
Predicate<Integer> isEven = n -> n % 2 == 0;
// Use the Predicate to filter the list
List<Integer> evenNumbers = numbers.stream()
.filter(isEven)
.collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]
}
}Practical Use Cases
- Filtering Collections:
Predicateis widely used to filter elements in collections and streams. - Conditional Checks: Used for conditional checks in various contexts.
- Validation: Can be used for validating inputs.
- Event Handling: Used to handle events based on conditions.
Summary
The Predicate interface is a functional interface in Java that represents a condition or a boolean-valued function of one argument. It is useful for filtering and matching purposes, and it can be implemented using lambda expressions and method references. The interface also provides methods for logical operations (and, or, negate) and a static method (isEqual) for equality checks. Predicate is a versatile tool in functional programming, particularly in the context of the Stream API and collections.








