Apache Commons’s MultiValuedMap interface allows mapping a single key to multiple values in Java, unlike java.util.Map, where a key can only be associated with a single value.

In the previous post, we have seen how to implement our own Multimap class in Java using a map and a Collection. This post will discuss various utility methods provided by Apache Commons’s MultiValuedMap interface:

1. Using put(), get(), asMap() methods

1. We know that if we put two values into a java.util.Map using the same key, the first value will be overridden by the second value. This behavior enforces the map’s key to associate with only one value, which is sometimes undesirable. Apache Commons provides MultiValuedMap that adds the new value to the collection stored against the key to avoid it. Any put() operations on a key will not override the values set by the previous put() operations on that key.

 
2. The get() method of Apache Commons’s MultiValuedMap interface returns a collection holding all values associated with the specified key. When containsKey(key) is false, an empty collection is returned, unlike Map.get(), which returns a null value. Please note that the underlying MultiValuedMap gets updated on doing any changes to the returned collection, and vice versa.

 
3. We can also convert the MultiValuedMap<K,V> to Map<K,Collection<V>> using asMap() method provided by MultiValuedMap. Any changes made to the returned map or the collections that serve as its values will update the underlying MultiValuedMap and vice versa.

 
Following is a simple Java program to demonstrate Apache Commons’s MultiValuedMap class in Java.

Download Code

Output:

John: [Adams, Tyler, Kennedy]
George: [Washington, Bush]

 
The above program uses ArrayListValuedHashMap implementation of MultiValuedMap interface that internally uses an ArrayList to store the values for a given key and allows the duplicate key-value pairs. Some implementations, like HashSetValuedHashMap, don’t allow duplicates. It all depends on the underlying data structure. For instance, an ArrayList supports duplicates, whereas a HashSet doesn’t.

2. Iterate over the MultiValuedMap

MultiValuedMap interface provides keySet(), entries(), values(), and keys() methods which are similar to the corresponding view collections of Map. To illustrate, consider the following MultiValuedMap used in the following functions as input to them.


Zachary –> Taylor
John –> Adams, Tyler, Kennedy
George –> Washington, Bush

⮚ Using keySet()

keySet() method returns a set view of the keys contained in this MultiValuedMap.

Download Code

Output:

George: [Washington, Bush]
Zachary: [Taylor]
John: [Adams, Tyler, Kennedy]

⮚ Using entries()

entries() method returns a Collection view of the mappings contained in this MultiValuedMap.

Download Code

Output:

George: Washington
George: Bush
Zachary: Taylor
John: Adams
John: Tyler
John: Kennedy

⮚ Using keys() and values()

key() method returns a MultiSet view of the keys contained in this MultiValuedMap while the values() method returns a Collection view of all values contained in this MultiValuedMap.

Download Code

Output:

[George:2, Zachary:1, John:3]
[Washington, Bush, Taylor, Adams, Tyler, Kennedy]

3. Remove and Search keys/values in the MultiValuedMap

Apache Commons’s MultiValuedMap provides the remove() method that removes all values associated with the specified key. It also has the removeMapping() method that removes the specified key-value pair from the MultiValuedMap. But note that no method is included for replacing the existing values for a particular key.

For searching key, values, or key-value pairs, MultiValuedMap has three methods – containsKey(), containsValue() and containsEntry(), that checks if the MultiValuedMap contains at least one key-value pair with the specified key, specified value, and the specified key-value pair, respectively.

Download Code

Output:

MultiValuedMap: {George=[Washington, Bush], John=[Adams, Kennedy]}

George key is deleted.
John Adams is removed.
John Kennedy is still there!

MultiValuedMap: {John=[Kennedy]}

 
We have seen that MultiValuedMap interface is implemented as Map<K,Collection<V>>. So one would expect the size() method to return the total number of distinct keys. Instead, it returns the exact number of key-value pairs contained in it. We should use keySet().size() or asMap().size() to get the total number of distinct keys.

That’s all about Apache Commons Collections MultiValuedMap Interface in Java.

 
Also See:

Google Guava’s Multimap class in Java

 
Reference: MultiValuedMap (Apache Commons Collections 4.1 API)