PROBLEM
Guava’s Collections2
is great when dealing with collections, but it quickly becomes rather clumsy and messy when we try to combine multiple actions together.
For example, say we have userIds
, which is a collection of user IDs. For each user ID, we want to retrieve the Employee
object and add it into an immutable set if the lookup is successful. So, we essentially want to perform a “tranform” and “filter” here.
By using strictly Collections2
, we ended up with the following code:-
final ImmutableSet<Employee> employees = ImmutableSet.copyOf(
Collections2.filter(
Collections2.transform(userIds,
new Function<String, Employee>() {
@Override
public Employee apply(String userId) {
return employeeService.getEmployee(userId);
}
}),
new Predicate<Employee>() {
@Override
public boolean apply(Employee employee) {
return employee != null;
}
}));
While it works, it may be confusing to those reading the code due to the nested functions.
SOLUTION
A better approach is to use FluentIterable
that allows us to write more natural top-to-bottom code:-
final ImmutableSet<Employee> employees = FluentIterable
.from(userIds)
.transform(new Function<String, Employee>() {
@Override
public Employee apply(String userId) {
return employeeService.getEmployee(userId);
}
})
.filter(new Predicate<Employee>() {
@Override
public boolean apply(Employee employee) {
return employee != null;
}
})
.toImmutableSet();
Leave a Reply