First, a quick introduction to functional programming. According to Wikipedia, functional programming is a paradigm of structuring your programs that treats computation as the evaluation of mathematical functions, instead of procedures and mutable data. I took a class on functional programming in college, and the professor summed it up succinctly: “Procedural programming describes elements of a program in terms of what they do, while functional programming describes elements of a program in terms of what they are.” For this reason, functional programs tend to be much shorter than ones that are written procedurally.
Guava is a project that contains several core libraries that Google relies on for their Java-based projects, including collections, caching, primitives support, concurrency libraries, common annotations, string processing, and I/O. Some of these libraries contain code that implements functional idioms.
Note: Google added a caveat on their wiki about using these.
As of Java 7, functional programming in Java can only be approximated through awkward and verbose use of anonymous classes. This is expected to change in Java 8, but Guava is currently aimed at users of Java 5 and above.
Excessive use of Guava’s functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code “a one-liner,” the Guava team weeps.
Predicates are a functional programming concept that describe a transformation on an input. Basically, take a list of objects as input, and apply the predicate to them.
In the Guava library, they are implemented simply as the following interface:
To use this interface, simply define a predicate and an apply method within it. To illustrate this, compare it to a procedural method of finding an entry in a phone book matching certain criteria.
(I realize this is a really inefficient way to search a phone book and we’d be better off with a binary search algorithm, but bear with me for the sake of example)
As you can see, we’re re-using a lot of code between these two methods. The only thing that’s really changing is the conditional logic within the if statement.
A better (or, at least, more functional programmy) way to do this would be to have a single method that loops through the phone book and applies the predicate at each iteration…
…then, define the predicates…
…and finally, call them in each method.
Sure, if you know you’re ultimately only going to need to match a couple of conditions, you’re probably better off going with the procedural option. The advantage of using predicates is that they’re extremely flexible, reusable, and it’s very easy to define new ones.