Predicate4j is a Java library with an expressive API for building complex predicates using a fluent interface. If you're a fan of the fluent API style in libraries like AssertJ, you'll likely enjoy using this one too.
For example, this code returns a Predicate<User>
that checks if the role is "admin" and the organization id is not null:
return where(User::role).isEqualTo("admin").and(User::organizationId).notNull();
It allows for the easy creation and combination of predicates for various types (including objects, collections, strings, numbers, etc.).
The library provides Java predicate builder with fluent API that:
- null safe
- type safe
- has zero compile-time dependencies
- supports predicates for various types:
- objects
- strings
- booleans
- numbers (integer, long, etc.)
- collections (List, Set, etc.)
Add the following dependency to your pom.xml
if you're using Maven:
<dependency>
<groupId>io.github.avegera</groupId>
<artifactId>predicate4j</artifactId>
<version>0.1.0</version>
</dependency>
For Gradle:
implementation 'io.github.avegera:predicate4j:0.1.0'
Predicate4j provides a fluent API for building and using Java predicates in a type-safe and null-safe manner. It allows to create complex conditions in a readable and maintainable way.
Let's use the following User
record for examples below:
record User(Long id, String status, int age, List<String> roles) {
}
And we create the following users:
List<User> users = Arrays.asList(
new User(1, "ACTIVE", 35, List.of("Admin", "Manager")),
new User(2, "ACTIVE", 18, List.of("User")),
new User(3, "INACTIVE", 12, List.of("Guest"))
);
Here's a basic example of how to create and use predicates with this library and Java Stream API:
List<User> activeUsers = users.stream()
.filter(where(User::status).isEqualTo("ACTIVE"))
.collect(toList());
The library supports various types of predicates for objects, strings, numbers, and collections.
List<User> adultUsers = users.stream()
.filter(where().number(User::age).isGreaterThanOrEqualTo(18))
.collect(toList());
List<User> usersWithSpecificStatus = users.stream()
.filter(where().string(User::status).startsWith("ACT"))
.collect(toList());
List<User> admins = users.stream()
.filter(where().list(User::roles).contains("Admin"))
.collect(toList());
It's possible to combine multiple predicates using logical operations:
List<User> activeAdultNotAdmins = users.stream()
.filter(where(User::status).isEqualTo("ACTIVE")
.and().number(User::age).isGreaterThan(21)
.and().list(User::roles).notContains("Admin"))
.collect(toList());
Pass your own predicate that not present in the library:
List<User> customPredicateUsers = users.stream()
.filter(where(User::status).accepts(status -> status.trim().length() > 5))
.collect(toList());