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.