1. Overview
In this short tutorial, weβll see how to negate a Predicate method reference using Java 11.
Weβll start with the limitations encountered in order to achieve this before Java 11. Then weβll see how the Predicate.not() method helps, as well.
2. Before Java 11
First, letβs see how we managed to negate a Predicate before Java 11.
To start with, letβs create a Person class with an age field and an isAdult() method:
public class Person {
private static final int ADULT_AGE = 18;
private int age;
public Person(int age) {
this.age = age;
}
public boolean isAdult() {
return age >= ADULT_AGE;
}
}
Now, letβs imagine we have a list of people:
List<Person> people = Arrays.asList(
new Person(1),
new Person(18),
new Person(2)
);
And we want to retrieve all the adult ones. To achieve that in Java 8, we can:
people.stream()
.filter(Person::isAdult)
.collect(Collectors.toList());
However, what if we want to retrieve the non-adult people instead? Then we have to negate the predicate:
people.stream()
.filter(person -> !person.isAdult())
.collect(Collectors.toList());
Unfortunately, we are forced to let go of the method reference, even though we find it easier to read. A possible workaround is to create an isNotAdult() method on the Person class and then use a reference to this method:
people.stream()
.filter(Person::isNotAdult)
.collect(Collectors.toList());
But maybe we donβt want to add this method to our API, or maybe we just canβt because the class isnβt ours. Thatβs when Java 11 arrives with the Predicate.not() method, as weβll see in the following section.
3. The Predicate.not() Method
The Predicate.not() static method has been added to Java 11 in order to negate an existing Predicate.
Letβs take our previous example and see what that means. Instead of using a lambda or creating a new method on the Person class, we can just use this new method:
people.stream()
.filter(Predicate.not(Person::isAdult))
.collect(Collectors.toList());
That way, we donβt have to modify our API and still can rely on the readability of method references.
We can make this even clearer with a static import:
people.stream()
.filter(not(Person::isAdult))
.collect(Collectors.toList());
4. Conclusion
In this short article, weβve seen how to leverage the Predicate.not() method in order to maintain usage of method references for predicates, even if they are negated.
