Take the 2-minute tour ×

I love using Guava's Iterables filters. But one common code snippet looks like:

  List foo = Lists.newArrayList(Iterables.filter(someCollection, somePredicate));  
  if (foo.isEmpty) {  
    // do empty  
  } else {  
    int count = foo.size();  // do non-empty  

This is wasteful, as I don't really need to build the "foo" list ever, all I need is to know if its empty or not and get a count of the number of elements.

I'd like to know the best practices for:
1) how do I test for isEmpty() without wasting time building the list into memory
2) Is there a way to get the size without iterating through all of the entries?
3) if there is no non-iterating solution to #2, is it better to just iterate and do count++?

share|improve this question
Don, thanks for editing to code. How did you do that? I've been trying to format code as code forever here. –  fishtoprecords Sep 29 '12 at 2:50
Select the region and click on the "{}" icon. –  Don Roby Sep 29 '12 at 2:52
After one year here on SO I finally learned that there are some formatting icons. I always indented the code manually. @fishtoprecords: Click on the edit link and look at what Don changed; you'll understand it at once, markdown is nice and easy. –  maaartinus Sep 29 '12 at 5:59

3 Answers 3

up vote 5 down vote accepted

FluentIterable.from(foo).filter(predicate).isEmpty() doesn't iterate any more than it has to.

But if you need the size, then you really want to use FluentIterable.from(foo).filter(predicate).size(), which won't store the elements but will just count up the ones that match the predicate.

share|improve this answer
The FluentIterable docs say that everything it can do, you can do with normal Iterables. While this is short, what does it do, exactly? Does it create the list? –  fishtoprecords Sep 29 '12 at 2:53
It's doing as little as possible to figure out whether that view is empty. Basically, it ends up iterating through the elements of someCollection, and as soon as it finds an element matching somePredicate, it returns false. If it gets all the way through someCollection's elements without finding a match, it returns true. –  Michael Hixson Sep 29 '12 at 3:12
But since he wants the size if it's not empty, you really just want to get the size to begin with and not call isEmpty at all. –  ColinD Sep 30 '12 at 1:03

Louis's answer is on the mark. Since you happen to be using a Collection, could also use Collections2.filter:

Collection<Foo> filteredFoos = Collections2.filter(foos, fooPredicate);
if (filteredFoos.isEmpty()) {

From the documentation:

Returns the elements of unfiltered that satisfy a predicate. The returned collection is a live view of unfiltered; changes to one affect the other.

share|improve this answer

There's no way to get the size of a filtered Iterable without iterating because you don't know which elements will match. Why not just use Iterables.size? If no elements match your predicate, isEmpty will have to iterate through the whole collection anyway.

share|improve this answer
Yes, but calling size() and then iterating means two full iterations. So I'd suggest copying to an ImmutableList/Set first. –  Sean Patrick Floyd Sep 29 '12 at 21:24
He says he doesn't need the contents: just whether it's empty or the size. –  ColinD Sep 30 '12 at 1:01

Your Answer


