Google Guava makes Java... usable

Posted on April 29, 2013 by Aaron Rotenberg
Post tagged: Java

Hello World! I’m planning to use this blog to collect the various discoveries I make about software development in my day-to-day job as a software engineer at CERTON, Inc. The perhaps-vain hope is that I will help some other poor soul who stumbles across my posts and finds the solution to the exact problem they were encountering at that instant. I’ll also probably post mathematical curiosities and software engineering commentary. The ultimate goal is to keep the quality level high enough that I feel less guilty of time-wasting writing here than if I were participating in the standard social grooming networks.

But, of course, you’re not here for me, you’re here for you. So let’s talk about Google Guava. For the unfamiliar, Guava is a collection of utilities for performing common tasks in Java, similar in spirit to Apache Commons or C++’s Boost. I was introduced to Guava by a fellow CERTON developer for the purpose of performing some set operations more easily in the selection logic in CertSAFE Modeler. Since then, the use of Guava in our codebase has expanded greatly, making it far and away the library we get the most use out of.

Even if you’re already using Guava, there’s most likely parts of it that you’re not using currently only because you don’t know they exist. I know I find myself saying “Wow! I didn’t know Guava had that!” on a regular basis. Here’s a quick list of the most common uses of Guava in the code I write. Undoubtedly there’s things I haven’t listed here because I haven’t discovered them yet—and you might just find something in this list that you wish you had known about a year ago.

  • Immutable collections. I’m a functional programming wonk, which means that, by default, I think in terms of immutable values and pure functions rather than updating state in place. It’s not like I never write imperative code; certainly, when clarity or efficiency calls for it you can’t beat a good ArrayList or HashMap. But I think I get more use out of Guava’s ImmutableSet, ImmutableMap, and ImmutableList than I do out of all of the java.util collection classes. Special mention goes to the ImmutableMap.Builder class, which has the neat property of rejecting duplicate keys rather than collapsing them like doing repeated put() calls on a Map does. Thus, using ImmutableMap.Builder serves a triple purpose: it documents that your insertion strategy will not add duplicate keys (usually because you’re looping on another collection and adding keys one-to-one); documents that the resulting collection is immutable and cannot be changed; and catches bugs by detecting duplicate keys or attempts to mutate the collection when you didn’t expect them.
  • Oddball collections. This includes BiMap, Multiset, ListMultimap, SetMultimap, Table, and more. After using these, you’ll be asking yourself why they weren’t in the Java Collections API to begin with.
  • Misclleaneous collection utilities. This includes Sets.union(), Sets.intersection(), Sets.difference(), Iterables.filter(), Iterables.transform(), and probably my single favorite method in Guava: Iterables.getOnlyElement(), which takes an Iterable that must have exactly one element and returns that element, throwing an unchecked exception if it contains zero or more than one element.
  • Optional. Despite the documentation disavowing any relationship between Optional and “any existing ‘option’ or ‘maybe’ construct from other programming environments”, Optional looks like, walks like, and quacks like an option type. Since I discovered Optional early in the development of CertSAFE, our team has adopted a soft “no nulls” convention—i.e., only use null if there’s a good reason not to use Optional, like strict performance requirements. (And definitely don’t use -1 or similar in-band signal.) Taking it a step further, I often write defensive fail-fast null checks on the parameters of public constructors and methods. (Since our codebase is Java 7, I use Objects.requireNonNull(), but pre-7 users can use Guava’s Preconditions.checkNotNull().) The result has been a very visible decrease in hard-to-reproduce NullPointerExceptions and a great deal more confidence in the quality of the code I write, including in areas that are hard to unit test.
  • Charsets. This is a little class that will save you a lot of silly redundant try-catch blocks, by giving you constants representing the six Charset objects that every JVM is guaranteed to support.

There are other Guava utilities that I use regularly as well, like Ordering, Joiner, the caches, etc., but the classes listed above are the ones I felt the most relief upon discovering.