Map vs. Multimap
Discover a safer alternative to mapping keys to multiple values in Java.
I need a Map with multiple values
At some point in your years of coding in Java, you have probably needed a
Map<K, Collection<V>>. If you haven’t needed one yet, give it some time… you will. There are more convenient ways to manage the
Collection part of the
Map using methods available since Java 8. If you have never used
computeIfAbsent before, it is a method well worth learning. The following is an example of creating a
Map<String, List<String>> using
computeIfAbsent works is simple. First, it looks in the map for a specified key (e.g. “A”). If it doesn’t find a value at the key, it evaluates the specified
Function, and stores the result in the
Map. It then returns either the value it found or the value it created and stored in the
Map. So basically,
computeIfAbsent is a
get with a
put where the value
put into the
Map is returned by the method. This method will guarantee a value always exists for any key looked up, but can be wasteful as a replacement for
get, since it will always result in a
put in the cases where you are looking up a key doesn’t exist.
Map has a null problem
One issue with using
Map is that implementations like
null keys, values and returns. If we ignore null keys for a second, the problem with
null values and returns is that if you look up a key that does not exist in the
Map, you will get a
null back. You can try and protect your code against the possibility of checking the
Map returns a null when calling
get or by using a safer method like
getOrDefault which could return an empty collection in the default case of a multi-valued
Map. The real solution would be to create a
Map type that knows that a missing key should result in an empty
Collection being returned when calling
get. This is what a
Don’t clown around with Maps w/ multi-values
If you need multi-valued
Map support, then consider using a
Multimap type from a library like Eclipse Collections, Google Guava or Apache Commons Collections. The method
put on a
Multimap will know that the values are multi-valued and should automatically call
add on the value containers. The method
get on a
Multimap knows when a key is not contained in the
Multimap, and that an empty
Collection should be returned instead. The point is that a
Multimap has more intimate knowledge about the value type it manages. A
Map may be provided the value type via generics, but it does not know that the value type must be a type of
Using a Multimap in Eclipse Collections
The following code shows the equivalent solution to the Map code above using a
Multimap type from Eclipse Collections.
First, I create a specific type of
Multimap, which in this case is a
MutableListMultimap. Then I can simply call put with each key and value. The
Multimap knows to create a backing
Collection container (in this case a
MutableList) for each new key. Finally, the call to
multimap.get(“D”) returns an empty
List is not stored in the
Multimap, so the Multimap will remain sparse and only contain the keys with actual values.
Multimap types in Eclipse Collections
There are several concrete Multimap types in Eclipse Collections. There are
Multimap is the parent interface.
MutableListMultimap is a leaf interface. The following are examples of the basic concrete
Multimap types that can be created by using the
Multimap, there are specific types based on the value containers (e.g.
Bag). There are specializations and sometimes optimizations that may exist for those types.
GroupBy should return a Multimap
Eclipse Collections is the only Java library that I am aware of today that returns a
Multimap from its
groupBy methods on each of its basic
Collection types. Each specific type like
MutableSet, will return the appropriate
Multimap type in its
groupBy method based on its type.
MutableList returns a
MutableListMultimap from its
groupBy method, and
MutableSet returns a
MutableSetMultimap. The following is an example of using
groupBy in Eclipse Collections.
For more examples of
groupBy, you can refer to the following blog.
EC by Example: GroupBy
Learn how to group elements of a collection using Eclipse Collections.
More information on Eclipse Collections Multimap
Nikhil Nanivadekar wrote a blog on Multimaps in Eclipse Collections a few years ago. He gives more in depth explanations on the implementations.
Multimap — How it works
In my previous blogs I explained how Eclipse Collections UnifiedMap and UnifiedSet works. In this blog, we will take a…
Do you need a Map with support for keys and multiple values? Consider using a
Multimap from Eclipse Collections. If you’re already using other
Collection types from Eclipse Collections, the
groupBy methods will give you easy access to creating appropriate
I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.
Other Java articles you may like
The 2022 Java Programmer RoadMap
An illustrated guide to becoming a Java Developer in 2022 with links to relevant courses
Top 22 Java Libraries and APIs Every Programmer Should Learn in 2022
Most essential Java libraries you can learn to become a better Java developer. It includes Java libraries for logging…