So I’ve been advocating Google Collections to all my colleagues since early this summer. Kevin Bourrillion said that one of his colleagues had told him that “not being able to use the Google Collections was like ‘coding with one hand tied behind his back.’“.
I couldn’t agree more with Kevin’s colleague!
Maybe the title of this blog entry is a bit strange. I mean “beautiful code”. I guess I could have said “less verbose” Java code, but hey, that doesn’t have the same magic sound to it!
Before I start this whole highly promotional rant about my new favorite java libraries, let me ask you a couple of questions:
How many times have you written something like this in your code:
Map<String, Map<Long, List<String>>> map = new HashMap<String, Map<Long,List<String>>>();
Or maybe something along these lines:
int a = 5; int b = 10; int compareTo = Integer.valueOf(a).compareTo(Integer.valueOf(b));
(Or with lots of ifs and elses;))
And how many times have you written something along these lines, just to read something from a file?:
File file = new File(getClass().getResource("/test.txt").getFile());
BufferedReader reader;
String text = "";
try {
reader = new BufferedReader(new FileReader(file));
String line = null;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
text += line.trim() + "\n";
}
reader.close();
reader = null;
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Yeah, I thought so… So what’s all the fuzz about? We’ve had Apache Commons Collections for several years. Why should we use yet another collections library?
I’ve read several comments like this one:
“Any Java programmer who’s been around awhile will already have accumulated most of these types of utility classes.”
Well, yes, that might be (and should hopefully) be true for most developers. But then again, there’s so much more to it than just getting rid of boiler plate code and reusing nifty utils! In this blog post I want to show you some of the things that really made me curious about – then later addicted to – Google Collections.
Like Jared Levy once said:
The library’s functionality simplifies your code so it’s easier to write, read, and maintain. While you can survive without such features, the Google Collections Library will improve your productivity as a developer, while reducing the amount of boilerplate low-level code you need to write.
Furthermore I want to show you some of the cool stuff that the guys over at Google have been churning up under the name Guava, and how YOU as a Java developer can utilize these nifty libraries to make your code cleaner, faster to write, and once and for all get rid of all a lot of that boiler plate code we all hate so much!
Google Guava is the Google Core Libraries for Java 1.6. It is still a rather immature library that is subject to changes over the coming months, but will eventually be THE Java library;) Google Collections will become part of Guava once Collections reaches it’s 1.0 release. Guava (and Google Collections) have been pioneered by several Google developers and is widely used in their “myriad of Java projects”. Among others, the people behind it are Kevin Bourrillion, Jared Levy, Crazy Bob Lee, Josh Bloch(!) (Chief Java Architect at Google etc.) and limpbizkit (have no clue what this guy’s name is – anyone?:p). Google Collections has been around since 2007 (I think?) but Guava saw the light of day in September 2009.
In part one of this blog series I’ll give you an introduction to Google Collections and show you how you can benefit from using Guava with Collections to reduce the amount of boilerplate code in your projects (and gain access to the new and faster data structures that they provide!). In part 2 we will dive deeper into the more advanced features that Guava and Collections offers to you as a Java developer, so stay tuned!
Google Collections at a glance
Obviously one blog post will not give Google Collections the amount of in-depth coverage it deserves, so I’ve decided to just spend some time with the basic yet powerful features that I use on a daily basis when I write code.
First of all, don’t do this:
Map<String, Map<Long, List<String>>> map = new HashMap<String, Map<Long,List<String>>>();
Do this:
Map<String, Map<Long, List<String>>> map = Maps.newHashMap();
or rather this, (with static imports):
Map<String, Map<Long, List<String>>>map = newHashMap();
Nice, right? Thanks to generics and those handy factory methods that the Collections guys have provided us with, we no longer have to write things that Java really should understand, right? Yeah, I know this will be part of JDK 7, and that’s great. But Google Collections is here, now!
Similar to the static utility methods that com.google.common.collect.Maps provide, we also have Lists and Sets.
Lists.newArrayList(); Sets.newHashSet();
…and more! Go check it out for yourself!
Populating lists and maps
When writing unit tests you often want to populate lists (or maps, or sets) with dummy data, and as the sloppy “duct-tape” programmer that I am, I’ve found the same code over and over again in my tests, along these lines:
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Yeah, I know. Dirty. I want an immutable list, populated with my dummy data, and I want to do it with one line of code! How? Well, that’s easy!
ImmutableList<String> of = ImmutableList.of("a", "b", "c", "d");
Same goes for Maps!
ImmutableMap<String,String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
I’ve grown really fond of these simple, yet powerful ways of writing code now. I wanted to write that line in an even shorter way, but couldn’t do it out of the box with static imports since both ImmutableList and ImmutableMap had the method “of”. But a quick workaround was simply to wrap these creational factory methods (and builder methods that they provide) in a collection util of our own. So for immutable maps and lists I simply write:
ImmutableMap<String,String> map2 = mapOf("key1", "value1", "key2", "value2")
or
ImmutableList<String> list2 = listOf("a", "b", "c", "d");
And if I want to populate an ArrayList (or a HashMap) I use:
ArrayList<String> list3 = arrayListOf("a", "b", "c", "d");
The choice is yours, obviously, but you have to admit, it’s quite neat compared to the “old” way, right?
Apart from the handy and clean ways of creating collections and populating them, we are also provided with lots of additional utility methods like filtering, set intersections and union, ordering and even some neat functional stuff! I’ll cover that in part 2!
Static imports and Eclipse templates
Before I wrap this up I want to tell you about how I use Collections even more efficiently when I code by using the Eclipse Code templates. (I assume you have similar features in IDEA and other IDE’s, so you can probably follow this recipe to some extent anyways):
Being a user of Eclipse I love shortcuts (check out Jaran’s post about MouseFeed and how you can easily learn Eclipse shortcuts).
Okay, Ctrl+Space is your friend! It’s also known as auto-complete:)
With Eclipse, you can create a template that binds to an auto-complete key-word and this is where the magic begins!
Instead of having to write Maps.newHashMap() or (even better – adding the method as a static import and writing newHashMap()) i simply type “newH”, hit ctrl+space and MAGIC!
Go to Window – Preferences in Eclipse. Go to Java -> Editor -> Templates and hit “New”.
The Name will be your shortcut, I usually name mine the method, i.e. “newHashMap” in this case.
Add your description if you like, for instance “Import static Maps.newHashMap”
And add the following Pattern:
${:importStatic(com.google.common.collect.Maps.newHashMap)}newHashMap();${cursor}
And that’s all there is to it! Now go crazy and add templates for all those method that you use alot!
Guava at a (very quick) glance
Last but not least, let me show you how you can use Guava to deal with the two remaining question I opened this blog post with:
Read lines from a file:
File file = new File(getClass().getResource("/test.txt").getFile());
List<String> lines = null;
try {
lines = Files.readLines(file, Charsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
Compare two primitives?
int compare = Ints.compare(a, b);
Convert a list of Integers to an array of primitive ints?
List<Integer> list = listOf(1, 2, 3, 4); int[] array2 = Ints.toArray(list);
Guava provides us with a comprehensive extension to the Core Java Libraries. Among other things we gain access to utilities for working with primitives through the Ints, Doubles, Floats, Shorts, Bytes and Bools classes in the com.google.common.primitives package. The com.google.common.io package provides utilities for working with streams, buffers, files etc, and the concurrent package provides classes like Futures, Callables and Executors to ease the pain of writing concurrent code. In addition to all of this, Guava also provides us with some additions to Collections and a really neat CharMatcher class, Joiner and Splitter classes that I will cover next time!
Check out the source code here:
svn checkout http://guava-libraries.googlecode.com/svn/trunk/guava-libraries-read-only
Next time we’ll take a deeper dive into Guava and also some of the more advanced stuff in Google Collections like how we can make Java just a tiny bit more “functional”, the über collection “Multimap” and how we can use mapping functions to transform collections. Stay tuned, and please share your comments on this with us! Have you tried Guava or Google Collections? What are your thoughts?



I believe that limpbizkit is Jesse Wilson, also member of Guice project.
Nice post. I’ve been also advocating Google Collections in my company since 0.4 version.
You don’t need to add those templates. In eclipse 3.5 (don’t know about earlier versions) you can add favorites for your static imports (preferences => java => editor => content assist => favorites). They then show up in your regular code completion all the time.
Hi Bartosz! Thanks for the info, and I’m glad you like the post! Stay tuned for next episode
I wasn’t aware of that Christophe! Thanks! Either way, the goal of the template or favorite was to ease development and they both accomplish the same thing:) If coding without Google Collections is like coding with one hand tied behind your back, coding without code completion would be like coding with a hockey stick :p
2nd try: generic were stripped from the previous post
ImmutableList<String> of = ImmutableList.of("a", "b", "c", "d");
you can also use the (even shorter) JDK method.
List<String> of = Arrays.asList("a", "b", "c", "d");
Hi Peter, thanks for commenting. Yes, you are right that the JDK provides us with the asList method, but the point here is that Google Collections gives you the ability to return that list as an ImmutableList. Furthermoer, you do not have such easy and accessible methods for the other Collection types such as Map or Set with the JDK. Google Collections does however give you these utility factory methods:) But yes, if all you want is a modifiable list, then asList would do the trick for sure!
Hi, thank you for the introduction.
It’s the same direction as Jakarta commons and Groovy…
Neat post! I’ll get these libraries into my pet project right away
Handy hint: Instead of using templates, you can add static import favorites to Eclipse:
Prefererences -> Java -> Editor -> Content Assist -> Favorites
Add the type here. Now Ctrl+Space will suggest importing the static methods for you.
Doh, I didn’t refresh this page before posting the comment much later, so I didn’t notice that Christophe already suggested this. Sorry about that
Wow, if those examples get you excited, maybe you should check out Scala. Code like
ImmutableList of = ImmutableList.of("a", "b", "c", "d");
just becomes
val of = List("a", "b", "c", "d")
But this is the least of things. Thanks to collection methods like map, filter, sort, partition, etc., you can drop collection-related boiler plate code like mad:
// get only people named "Steve" from a list called "people" and sort by last name
people.filter(_.firstName == "Steve").sort(_.lastName < _.lastName)
Much ado about nothing.
Hi Steve, yes Scala is definitely exiting but as Java is not a functional language, Google Collections and Guava is a great leap in the right direction of providing functional-like approaches to writing Java code. I will cover how you can filter, sort and partition with Collections in the next blog post, and as you will then see it is actually quite nice! But sure, Scala is great and all, so if that is the language you want to use then that’s your choice
This post was to enlighten people about the options you actually have right here and now, with plain old Java!
In IntelliJ IDEA you can use live templates to create shortcuts. You can add
them under ‘Preferences’ -> ‘Live Templates’
Hi, thanks for this post.
Can’t print it right from Firefox
Confirmed, limpbizkit is myself. Great posts, we’ve been sharing them around within Google!
@Jesse Wilson: Thanks a lot man! Highly appreciated and motivating to hear that you like our posts, and even more so that you share them within Google! Keep up the good work!
this is compliance RTSJ, so that i will not using this library.
New to Guava – does anyone have a list of good Eclipse favorites to add for Guava development?
I happened to use a useful interface in guava: Multimap.
Thank to Multimap you can define a variable like this:
Multimap multimap = HashMultimap.create();
whenever you need to handle a map with a list as value, i.e.:
Map<String, List> multimap = new HashMap<String, List>;
Quite handy if you have to loop some other collection to populate the map and you don’t want to deal with the list of values mapped to same key.
Hi Dimitri! Yes, Multimap is very useful! Make sure you check out the other parts of this series, where we cover Multimaps in part 4 here:
http://codemunchies.com/2009/11/preconditions-multimaps-and-partitioning-with-google-collections-part-4/
Cheers,
Aleks
arrayListOf does not exist, does it? The guava documentation does not list this function.
Your comment got lost in the approval list, sorry.
The arrayListOf method is a method we have implemented ourselves, but all it does it wrap the ImmutableList.of and ImmutableMap.of static methods to try and make it even nicer. Therefore you do not find it in the Guava documentation.
Map<String, Map<Long, List>>map = newHashMap();
Nice, right? Thanks to generics and those handy factory methods that the Collections guys have provided us with, we no longer have to write things that Java really should understand, right?
Only thanks to the great Java generics we need libraries like this.