JavaEnterprise JavaThe Google Collections Library, An Update

The Google Collections Library, An Update

A couple of weeks ago, I wrote an article about the Google Collections Library (http://www.developer.com/java/ent/article.php/3735441), which gave some examples of the exciting features in this new open source library. The article carried a caveat that the 0.5 version of the library carried a few warnings, including the possibility that the API could change.

Less than 24 hours after the article was published, a new snapshot of the library was released, and this broke a couple of examples in the article. On top of that, a couple of bugs managed to sneak through into the article (this is the reason why developers typically use IDEs rather than word processors to write code ). As a result, this is a very short update article correcting the mistakes in the article, and also updating the examples where the API changed.

The new snapshot is still labeled 0.5 alpha on the site, so this is especially confusing. The snapshot itself carries a date that is the best way to track which version of the library you are using. This article will cover the changes in the file google-collect-snapshot-20080321.zip available from the Google Collections Library project page.

Correcting the Mistakes

First, there were a couple of small mistakes in the examples (typos, really) that I did not find until after the article had been published. These were in the examples for Multimap and Multiset. The original article had examples that read:

Multimap<Integer, String> numbers =
   Multimaps.newArrayListMultiMap();
...

and

Multiset<String> histogram =
   Multisets.newHashMultiSet();
...

If you tried out these examples, you will have probably already found the mistakes. They are in the capitalization of the newXXXMultiXXX methods. The name of these collections is Multimap and Multiset respectively, not MultiMap and MultiSet (even though I always, always want to type them like that).

So, the correct code examples should have been:

Multimap<Integer, String> numbers =
   Multimaps.newArrayListMultimap();

and

Multiset<String> histogram =
   Multisets.newHashMultiset();

The API Changes

The other changes in this new snapshot pertain to the immutable collections, or to be precise: ImmutableList and ImmutableSet.

The previous way of creating a new ImmutableList was to use a static convenience creator on the Lists class, as demonstrated in the example:

final List<String> immutableList =
   Lists.immutableList("Hello", "World");
// UnsupportedOperationException!
immutableList.add("!");

Using Lists.immutableList() to create a new ImmutableList has now been replaced by a static method on the ImmutableList class. The new way to do this is:

final List<String> immutableList =
   ImmutableList.of("Hello", "World");
// UnsupportedOperationException!
immutableList.add("!");

Likewise for ImmutableSet, just like an ImmutableList but guaranteeing unique values. This has a similar creation method:

final Set<String> immutableSet =
   ImmutableSet.of("Hello", "World");

These are not huge changes, but they’re enough to cause some confusion if you just copied the code out of the article and tried it.

There is also a new way of converting an existing List (or Set) into an ImmutableList (or ImmutableSet) that more clearly explains to the developer what is going on. Instead of using Lists.immutableList(otherList) that could be mistaken for the same kind of inexpensive (but less safe) operation that Collections.unmodifiableList carries out, the new method to do this is: ImmutableList.copyOf(otherList). There is the equivalent method for ImmutableSet as well. The new copyOf method name leaves no doubt as to exactly what is going on to create the ImmutableList (or Set).

This affects the predicate example from the previous example, which changes from:

finalList<Car> premiumCars =
   Lists.immutableList(Iterables.filter(cars, expensiveCar));

to:

finalList<Car> premiumCars =
   ImmutableList.copyOf(Iterables.filter(cars, expensiveCar));

Finally, there is a helpful note for the Function example because a couple of people hit this problem when trying it out. The problem relates to the definition of the Function which maps the ints through the numbers BiMap:

final Function<Integer, String> nameForNumber =
   new Function<Integer, String>() {
   public String apply(Integer from) {
      return numbers.get(from);
   }
}

For this to compile correctly, the numbers in BiMap must also have been declared final. Because numbers is a local variable, the scoping issues surrounding the alteration of the numbers reference once the Function has been declared could lead to unintended results; hence, the numbers BiMap must be declared final to compile correctly.

Conclusion

If this article brings home anything, it should be a reinforcement of the warning that the Google Collections Library is subject to changes in the API and will be for some time to come. This warning is not intended to put you off using the library by any means, but just to make sure you know what you are getting in to. None of these changes should be a problem for anyone with a decent search/replace in their editor or IDE, but if this kind of thing really bothers you, you may want to think twice before integrating the Google Collections Library throughout your multi-million line project, at least until the API is a bit more stable.

If you would like to keep track of the latest changes in the API, I can recommend the PublicObject blog by Jesse Wilson as a good way to keep up. Jesse is a regular contributor to the Google Collections Library and, through his blog, follows the latest developments in the Google Collections Library as well as discussing many other topics of interest to Java developers.

About the Author

Dick Wall is a developer advocate for Java technologies at Google, based in Mountain View, part of the Google Developer Program. He also co-hosts the Java Posse podcast, a regular Java-centric news and interviews show that can be found at http://javaposse.com.

Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.
Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.

Latest Posts

Related Stories