[Google Guava] – One class to rule’em all – FluentIterable

Google Guava has a lot of interesting utility classes, just to name a few: Optional, Joiner, Splitter, EventBus, Collections2 etc. But the essence of the whole library is condensed in just one single class – FluentIterable.

The FluentIterable class let’s you combine a set of operations on a collection in a single pipeline, plus it has some nifty methods too :).

To start a pipeline, you should use the simple FluentIterable.from(collection) method:

Could not embed GitHub Gist 5177971: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

Then you can perform typical collection operations. For the purpose of the example, let assume that we want to square all even numbers from 1 to 100 and select from the result the first number that is greater than 17 and smaller than 50.

Could not embed GitHub Gist 5178106: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

Note that for a range comparison I have used the Guava Range class which is a cool utility for dealing with ranges. One can also replace the “generateInput” method with a combination of a ContiguousSet and Range invocations:

Could not embed GitHub Gist 5178252: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

The last but not the least interesting method in the FluentIterable is the transformAndConcat method. It allows to perform a transformation of a collection of some objects and merge the outputs, assuming that the result of a single item transformation was also a collection. This is very handy for situations like making a flat structure from some kind of Tree or a nested List. A common example is a list of files in a tree structure of the file system.

Could not embed GitHub Gist 5178381: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

Note in the above example, that I have used an “identity function”. The identity function is a function that simply returns its input.

We are near the end, so for the close up I would like to tell a few words about performance. I have done some tests using the Google Caliper benchmarking library. The case was about squaring every item of a collection which was an even number. I have made two implementations:

…a vanilla Java one:

Could not embed GitHub Gist 5178414: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

… and a Guava based one:

Could not embed GitHub Gist 5178440: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

The test:

Could not embed GitHub Gist 5178445: API rate limit exceeded for 213.251.182.110. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)

The test was run 10 times (10 reps) for 20 trials. On the average the Guava solution took about 1,5x time of the Java one.

All in all I think that the performance penalty is not very big and it is beneficial to use the FluentIterable class for the sake of coding pleasure, readability and testability.

 

 

 

 

Leave a Reply

Notify me of followup comments via e-mail. You can also subscribe without commenting.