Guava

No discussion of modern Java development would be complete without mentioning Guava.

Google started releasing some internal Java code as open-source under the name Google Collections back in 2007. Its creation and architecture were partly motivated by generics inroduced in JDK 1.5. This became much more than only collection support and was rebranded as guava. Guava contains a lot of extremely useful code and gives some hints into modern Java practice.

Collections

It adds a bunch of very useful Collection-related classes and interfaces:

  • Collections2 - Utility methods for filtering, tranforming, and getting all possible permutations of Collections.
  • BiMap - A Map that goes both ways (one-to-one mapping where values can map back to keys).
  • Multimap - A Map that can associate keys with an arbitrary number of values. Use instead of Map<Foo, Collection<Bar>>.
  • Multiset - A set that also keeps tracks of the number of occurances of each element.
  • Table - Uses a row and column as keys to values.

For every Collection type, it also has a static utility class with useful methods, for example:

  • Lists: newArrayList, asList, partition, reverse, transform
  • Sets: newHashSet, filter, difference, union
  • Maps: newHashMap, newTreeMap, filterKeys, filterValues, asMap

Objects

Guava’s Objects class contains a bunch of useful methods for dealing with a lot of the boilerplate code in generic Java, such as writing equals and hashCode methods.

  • Objects.equal(Object, Object) - null safe equals.
  • Objects.hashCode(Object...) - an easy way to get a hash code based on multiple fields of your class.
  • Objects.firstNonNull(Object,Object) - one way to deal with null-return values (returns the first non-null value).

Concurrency

It also contains some concurrency support, such as the following:

ListenableFuture
A ListenableFuture allows you to register callbacks to be executed once the computation is complete, or if the computation is already complete, immediately. This simple addition makes it possible to efficiently support many operations that the basic Future interface cannot support.
 1 ListeningExecutorService srv = MoreExecutors
 2 	.listeningDecorator(Executors.newFixedThreadPool(10));
 3 ListenableFuture<Rocket> rocket = srv.submit(new Callable<Rocket>(){
 4   public Rocket call() {
 5     return launchIntoSpace();
 6   }
 7 });
 8 Futures.addCallback(rocket, new FutureCallback<Rocket>() {
 9   // we want this handler to run immediately after we launch!
10   public void onSuccess(Rocket rocket) {
11     navigateToMoon(rocket);
12   }
13   public void onFailure(Throwable thrown) {
14     launchEscapePod();
15   }
16 });

Functional Programming

Guava contains a lot of Functional programming paradigms. It has interfaces (Function, Predicate) and utility classes (Functions, Predicates) for dealing with functional programming in Java. However, the Guava team warns against overuse of these classes in the following from the guava wiki.

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.

Optional

Guava also has Optional for avoiding null return values (which is similar to Nat Pryce’s Maybe class and Scala’s Option class we will discuss later).

You can use Optional.of(x) to wrap a non-null value, Optional.absent() to represent a missing value, or Optional.fromNullable(x) to create an Optional from a reference that may or may not be null.

After creating an instance of Optional, you then use isPresent() to determine if the there is a value. Optional provides a few other helpful methods for dealing with missing values:

  • or(T) - Returns the given default value if the Optional is empty.
  • or(Supplier<T>) - Calls on the given Supplier to provide a value if the Optional is empty.
  • or(Optional<? extends T>) - Useful for method-chaining; returns the given Optional if the Optional is empty.
  • orNull() - simply unwraps the value (not recommended).
  • asSet() - Returns a set of one element if there is a value, otherwise an empty set.

Other Useful Classes

Guava also contains tons of helpful utilities for general software development, such as the following:

EventBus
EventBus allows publish-subscribe-style communication between components without requiring the components to explicitly register with one another (and thus be aware of each other).
CacheBuilder
Builds caches that can load and evict values. Caches are tremendously useful in a wide variety of use cases. For example, you should consider using caches when a value is expensive to compute or retrieve, and you will need its value on a certain input more than once.
BloomFilter
Bloom filters are a probabilistic data structure, allowing you to test if an object is definitely not in the filter, or was probably added to the Bloom filter.
ComparisonChain
A small, easily overlooked class that’s useful when you want to write a comparison method that compares multiple values in succession and should return when the first difference is found. It removes all the tedium of that, making it just a few lines of chained method calls.
CharMatchers
A really fast way to match characters, such as whitespace and digits.
Throwables
Lets you do some nice things with throwables, such as Throwables.propagate which rethrows a throwable if it’s a RuntimeException or an Error and wraps it in a RuntimeException and throws that otherwise.

Guava has great documentation available on the google-code wiki.