Is there an elegant way to remove nulls while transforming a Collection using Guava?
There's already a predicate in Predicates
that will help you here -- Predicates.notNull()
-- and you can use Iterables.filter()
and the fact that Lists.newArrayList()
can take an Iterable
to clean this up a little more.
Collection<String> resourceIds = Lists.newArrayList(
Iterables.filter(
Iterables.transform(matchingComputers, yourFunction),
Predicates.notNull()
)
);
If you don't actually need a Collection
, just an Iterable
, then the Lists.newArrayList()
call can go away too and you're one step cleaner again!
I suspect you might find that the Function
will come in handy again, and will be most useful declared as
public class Computer {
// ...
public static Function<Computer, String> TO_ID = ...;
}
which cleans this up even more (and will promote reuse).
A bit "prettier" syntax with FluentIterable
(since Guava 12):
ImmutableList<String> resourceIds = FluentIterable.from(matchingComputers)
.transform(getResourceId)
.filter(Predicates.notNull())
.toList();
static final Function<Computer, String> getResourceId =
new Function<Computer, String>() {
@Override
public String apply(Computer computer) {
return computer.getResourceId();
}
};
Note that the returned list is an ImmutableList
. However, you can use copyInto()
method to pour the elements into an arbitrary collection.
It took longer than @Jon Skeet expected, but Java 8 streams do make this simple:
List<String> resourceIds = computers.stream()
.map(Computer::getResourceId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
You can also use .filter(x -> x != null)
if you like; the difference is very minor.