1. What is a Predicate?
A Predicate is a functional interface in Java 8 that checks a condition and returns a boolean DayOfWeek
returns: true or false. It has a single abstract method:
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
This means that a Predicate is used to apply a condition to an input of type T and check whether it is satisfied.
2. Simple example of Predicate
Here is a simple example to demonstrate how a Predicate works:
Predicate<Integer> isEven = n -> n % 2 == 0; // Checks whether a number is even
System.out.println(isEven.test(4)); // true
System.out.println(isEven.test(5)); // false
3. Combine Predicates
Java 8 allows you to combine predicates. There are three main ways to do this:
and(): Combines two predicates and returnstrueif both predicates aretrue.or(): Combines two predicates and returnstrueif at least one of the predicates istrue.negate(): Returns a Predicate that is the opposite of a given Predicate.
4. Predicate chaining: AND example
The and() method allows two predicates to be combined so that the condition is only met if both predicates return true:
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositiveAndEven = isPositive.and(isEven);
System.out.println(isPositiveAndEven.test(4)); // true
System.out.println(isPositiveAndEven.test(-4)); // false
System.out.println(isPositiveAndEven.test(5)); // false
5. Predicate chaining: OR example
The or() method allows two predicates to be combined so that the condition is satisfied if at least one of the predicates returns true:
Predicate<Integer> isNegative = n -> n < 0;
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isNegativeOrEven = isNegative.or(isEven);
System.out.println(isNegativeOrEven.test(4)); // true
System.out.println(isNegativeOrEven.test(-5)); // true
System.out.println(isNegativeOrEven.test(5)); // false
6. Predicate chaining: NEGATE example
The negate() method returns a Predicate that is the opposite of a given Predicate:
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isNotPositive = isPositive.negate();
System.out.println(isNotPositive.test(4)); // false
System.out.println(isNotPositive.test(-4)); // true
7. More complex examples and applications
One can combine these methods to create more complex logical conditions:
Predicate<String> isNotNull = Objects::nonNull;
Predicate<String> isNotEmpty = s -> !s.isEmpty();
Predicate<String> hasLengthOf5 = s -> s.length() == 5;
Predicate<String> complexPredicate = isNotNull.and(isNotEmpty).and(hasLengthOf5);
System.out.println(complexPredicate.test("Hello")); // true
System.out.println(complexPredicate.test("Hi")); // false
System.out.println(complexPredicate.test("")); // false
System.out.println(complexPredicate.test(null)); // false
8. Use in streams
Predicates are particularly useful in combination with Java Streams as they can be used to filter data:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, -1, -2, -3);
List<Integer> positiveNumbers = numbers.stream()
.filter(isPositive)
.collect(Collectors.toList());
System.out.println(positiveNumbers); // [1, 2, 3, 4, 5]
9. Best Practices
- Readability: Chain only as many predicates as necessary to ensure the readability of your code.
- Reusability: Define predicates as separate variables and combine them to be reusable.
- Debugging: Use meaningful names for your predicates to make debugging easier.
With this basic knowledge of predicates and their possible combinations, you should be able to use 80% of the functionalities in practical applications. Good luck using Predicate Chains in your projects!
![[EN] Java Predicate Chain](/images/JavaPredicateBeitragsHeader.png)