BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Google Collections 1.0 Offers Enhanced Implementations of the Java Collections Framework

Google Collections 1.0 Offers Enhanced Implementations of the Java Collections Framework

This item in japanese

The Google Collections Library, version 1.0-final, was released on December 30, 2009. You may download it at http://code.google.com/p/google-collections/. The library is the brainchild of Google engineers Kevin Bourrillion and Jared Levy. It has seen substantial growth in recent years thanks to the contributions of other Google engineers (like Doug Lea, Josh Bloch and Bob Lee), and the open source community at large.

The library aims at extending the Java platform's built-in collections library. The JDK collections library – as it stands today – lives in the java.util.* package. It is rooted primarily by a handful of interfaces: java.util.Collection (the super interface), java.util.Set, java.util.SortedSet, java.util.Map, and java.util.List. These interfaces dictate the contract behind the various implementations that ship with the JDK. java.util.Set loosely defines a collection of unordered, unique elements; java.util.SortedSet describes a collection of ordered, unique elements; java.util.Map defines an association – often termed a dictionary in other languages – of keys and values, and java.util.List defines an ordered collection of elements whose cardinality is variable. The original framework, designed by Josh Bloch when he worked at Sun, revolves around three ideas: interfaces, implementations (both concrete and abstract) and algorithms that allow you to manipulate the collections in an extensible way. These interfaces were introduced as a substantial overhaul of the classes provided by the earlier JDKs (java.util.Vector, java.util.Hashset, etc). Josh Bloch indicated in this 2008 Google Techcast that the Google Collections Library was developed in a way that he was comfortable with.

The Google Collections Library also offers new utility implementations and a focused set of libraries concerned with concurrency, including immutable collection implementations. “Immutability” guarantees that no other actor in the system – even the implementation itself – will change the state of the collection, while “unmodifiable” (as guaranteed by the JDK’s java.util.Collections class’ unmodifiable* factory methods) only guarantees that the client of the collection – the user – can never change the collection. Often, the implementations are not JDK wrappers, but finely tuned, memory sensitive, re-implementations of the interfaces. The Google Collections Library provides numerous static factory methods and builders (often both) by which objects may be created. Sometimes these are simply utility methods to subvert redundant type declaration:

import com.google.common.collect.*;
...
HashSet<String> hashSet = Sets.newHashSet();
LinkedHashSet<String> linkedHashSet = Sets.newLinkedHashSet();
ArrayList<String> arrayList = Lists.newArrayList();
LinkedList<String> linkedList = Lists.newLinkedList();

Other times, the static factory methods or builders are used because the implementations have no public constructors. The creation of subclasses is undesirable in many cases because the immutability contract might be compromised by a subclass. The Immutable* interfaces in the Google Collections Library signal to the client of the collections that a collection carries a guarantee of immutability, as well as implements the semantics of their JDK base interfaces’ contract. Users of the collections should pass around references to the Immutable* interface where possible.

import com.google.common.collect.*;
...
ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 4, 5);
ImmutableList<String> immutableList = ImmutableList.of("a,b,c,d,e,f,g".split(","));

The library offers some unique library implementations, too, including the MultiMap and MultiSet collections which describe collections of objects whose cardinality or frequency in the collection you can interrogate. Thus, to store multiple values associated with one key, you might use the following:

Multimap<String, Integer> personAndFavoriteNumbers = ArrayListMultimap.create();
personAndFavoriteNumbers.put("josh", 42);
personAndFavoriteNumbers.put("josh", 7);
Collection<Integer>numbers = personAndFavoriteNumbers.get("josh"); // doesn't return Integer
System.out.println(numbers .size()) ; // == 2

Note that get(String) returns a view associated with a key. If there are no values in the map for a given key, an empty collection will be returned. If you add items to the view collection, they are reflected in the Multimap:

Collection<Integer>numbers = personAndFavoriteNumbers.get("josh");
System.out.println(numbers .size()) ; // == 2
numbers.add( 0) ;
System.out.println(numbers .size()) ; // == 3
System.out.println(personAndFavoriteNumbers.get("josh").size() ) ; // == 3

There are also numerous concurrent implementations available for all the custom interfaces:

ConcurrentHashMultiset<String> concurrentHashMultiset =
ConcurrentHashMultiset.create(Arrays.asList("a,b,c,d,e,f".split(",")));

The Google Collections Library offers niceties for working with various functional programming idioms using the com.google.common.base.Predicate class:

import com.google.common.collect.*;

Iterable<Integer> filteredSet = Iterables.filter( someIterable, new Predicate<Integer>(){
public boolean apply( Integer integer) {
return integer > 0 ;
}
}) ;

Speaking to the library’s suitability, the library has a track record of production deployment at Google, and an exhaustive unit test suite of more than 25,000 tests. While the Google Collections Library is very promising, there are alternatives. Every iteration of the JDK benefits from new collections improvements. The Apache commons collections project also has some interesting collections implementations that predate this library by many years, though you will find that they are not as generics friendly. Looking forward, Kevin Bourrillion has said that the intention of the project was to formalize this library and then submit it to the JCP.

Rate this Article

Adoption
Style

BT