Google Guava MultiMaps

Guava?

This is the first in a series of posts where I’ll be attempting to explain and explore Google’s awesome Guava java library.

I first came across Guava whilst searching for generic versions of Apache Commons Collections – I needed a Bimap and was fed up with having to pepper my code with casts – however what I found was much much better.

Not only does it contain various implementations of more complex (but useful) collection types-Multimaps,Multisets,Bimaps- which I’ll discuss in detail, but also facilities to support a more functional style of programming with immutable collections, andfunction andpredicate objects. This has both completely changed the way I write java, and at the same time made me increasingly frustrated with Java’s sometimes clunky syntax, something I intend to explore in further posts.

Anyway enough with the introduction, and on with the good stuff. The first thing I’d like to take a look at is the Multimap, which is probably the single Guava feature I’ve made the most use of.

Mutlimaps

So, how often have you needed a data structure like the following?

Map<String,List<MyClass>> myClassListMap test2
                              = new HashMap<String,List<MyClass>>()

If you’re anything like me, fairly frequently. And don’t you find yourself writing the same boilerplate code over and over again?

To put a key/value pair into this map, you need to first check if a list already exists for your key, and if it doesn’t create it. You’ll end up writing something along the lines of the following:

void putMyObject(String key, Object value) {
    List<Object> myClassList = myClassListMap.get(key);
    if(myClassList == null) {
        myClassList = new ArrayList<object>();
        myClassListMap.put(key,myClassList);
    }
    myClassList.add(value);
}

Bit of a pain, and what if you need methods to check a value exists, or remove a value, or even iterate over the entire data structure. That can be quite a lot of code.

Never fear Guava is here!

Just like the standard java collections, Guava defines several interfaces and matching implementations. Usually you want to code to an interface, and only worry about the implementation when you create it. In this case we’re interested in Multimaps.

So using a multimap, we could replace the data structure declaration with the following:

Multimap<String,Object> myMultimap = ArrayListMultimap.create();

There’s a few things to note here. The generic type declaration should look very familiar, this is exactly how you would declare a normal Map.

You may have been expecting to see new ArrayListMultimap<String,Object>() on the right-hand side of the equals. Well, all Guava collection implementations offer a create method, which is usually more concise and has the advantage that you do not have to duplicate the generic type information.

Guava in fact adds similar functionality to the standard Java collections. For example, if you examine com.google.common.collect.Lists, you’ll see static newArrayList(), and newLinkedList() methods, so you can take advantage of this conciseness even with the standard Java collections. (I’ll aim to cover this in more detail in a future post).

So we’ve declared and instantiated a multimap, how do we go about using them? Easy just like a normal map!

public class MutliMapTest {
    public static void main(String... args) {
  Multimap<String, String> myMultimap = ArrayListMultimap.create();

  // Adding some key/value
  myMultimap.put('Fruits', 'Bannana');
  myMultimap.put('Fruits', 'Apple');
  myMultimap.put('Fruits', 'Pear');
  myMultimap.put('Vegetables', 'Carrot');

  // Getting the size
  int size = myMultimap.size();
  System.out.println(size);  // 4

  // Getting values
  Collection<string> fruits = myMultimap.get('Fruits');
  System.out.println(fruits); // [Bannana, Apple, Pear]

  Collection<string> vegetables = myMultimap.get('Vegetables');
  System.out.println(vegetables); // [Carrot]

  // Iterating over entire Mutlimap
  for(String value : myMultimap.values()) {
   System.out.println(value);
  }

  // Removing a single value
  myMultimap.remove('Fruits','Pear');
  System.out.println(myMultimap.get('Fruits')); // [Bannana, Pear]

  // Remove all values for a key
  myMultimap.removeAll('Fruits');
  System.out.println(myMultimap.get('Fruits')); // [] (Empty Collection!)
 }
}

One thing you may be wondering, is why does the get method return a Collection and not a List, that would be much more useful. Indeed it would. The problem is there are several different implementations available, some use Lists-ArrayListMultimap, LinkedListMultimap etc. – and some use Sets – HashMultimap,TreeMultimap among others.

To handle this – if you need to work directly with the Lists, or Sets in the map – there are several subinterfaces defined. ListMultimap, SetMultimap, and SortedSetMultimap. These all do what you’d expect, and their methods that return collections, will return one of the approprite type.

ie

ListMutlimap<String,String> myMutlimap = ArrayListMultimap.create();

List<string> myValues = myMutlimap.get('myKey');  // Returns a List, not a Collection.

That’s basically all there is to them. I recommend looking at the API:http://docs.guava-libraries.googlecode.com/git-history/release09/javadoc/com/google/common/collect/Multimap.html, where you can find the various implementations, you should be able to find one that suits your needs.


Reference:
Multimaps – Google Guava from our JCG partner Tom Jefferys at the Tom’s Programming Blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

2 Responses to "Google Guava MultiMaps"

  1. Andrei Bulanau says:

    27 // Removing a single value
    28 myMultimap.remove(‘Fruits’,’Pear’);
    29 System.out.println(myMultimap.get(‘Fruits’)); // [Bannana, Pear]

    probably [Bannana, Apple] ?

  2. Alberto Ivo says:

    Hello.. nice article!
    But in the MultiMapTest class… in the line 29, shouldn’t the result be [Banana, Apple] instead of [Banana, Pear], considering taht you removed [Pear] in the line 28?
    Thanks! Keep up the good work!

Leave a Reply


× seven = 21



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close