Iterate over a Guava Multimap
A Multimap is a collection that maps keys to values, where each key may be associated with multiple values. Let us delve into understanding how to iterate over a Guava Multimap.
1. Introduction
The Guava library provides a Multimap interface that lets us map a single key to multiple values. This is helpful when you want a data structure similar to a Map, but with the flexibility to handle multiple values per key.
1.1 Pros of Multimap
- Eliminates the need for
Map<Key, List<Value>>constructs, making code cleaner. - Provides various implementations for different use cases, like sorted or unordered storage.
- Built-in methods for key-value pair iteration make it easy to manage and retrieve values.
1.2 Dependency
To use Multimap, you need to add the Guava library to your project.
If you’re using Maven, add the following dependency:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>latest_jar_version</version>
</dependency>
If you’re using Gradle, add:
implementation 'com.google.guava:guava:latest_jar_version'
2. Multimap Implementation
Guava provides different Multimap implementations, such as:
ArrayListMultimap– Allows duplicate key-value pairs.HashMultimap– Does not allow duplicate key-value pairs.LinkedListMultimap– Maintains insertion order.TreeMultimap– Stores keys and values in sorted order.
Here’s an example that demonstrates the behavior of each type of Multimap implementation:
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.Multimap;
public class MultimapExample {
public static void main(String[] args) {
// ArrayListMultimap - Allows duplicate values for the same key
Multimap<String, String> arrayListMultimap = ArrayListMultimap.create();
arrayListMultimap.put("fruit", "apple");
arrayListMultimap.put("fruit", "apple"); // Duplicate allowed
arrayListMultimap.put("fruit", "banana");
System.out.println("ArrayListMultimap: " + arrayListMultimap);
// HashMultimap - Does not allow duplicate key-value pairs
Multimap<String, String> hashMultimap = HashMultimap.create();
hashMultimap.put("fruit", "apple");
hashMultimap.put("fruit", "apple"); // Duplicate ignored
hashMultimap.put("fruit", "banana");
System.out.println("HashMultimap: " + hashMultimap);
// LinkedListMultimap - Maintains insertion order
Multimap<String, String> linkedListMultimap = LinkedListMultimap.create();
linkedListMultimap.put("fruit", "banana");
linkedListMultimap.put("fruit", "apple");
linkedListMultimap.put("fruit", "orange");
System.out.println("LinkedListMultimap: " + linkedListMultimap);
// TreeMultimap - Stores keys and values in sorted order
Multimap<String, String> treeMultimap = TreeMultimap.create();
treeMultimap.put("fruit", "banana");
treeMultimap.put("fruit", "apple");
treeMultimap.put("fruit", "orange");
System.out.println("TreeMultimap: " + treeMultimap);
}
}
2.1 Code Explanation and Output
In the main method, we create and manipulate each type of Multimap, showcasing their unique behaviors:
- ArrayListMultimap: The
ArrayListMultimapallows duplicate values for the same key. In this example, the key “fruit” is mapped to two “apple” values, which are allowed since duplicates are supported. The resulting output shows three values for the “fruit” key: two “apple” entries and one “banana” entry. - HashMultimap: The
HashMultimapdoes not allow duplicate key-value pairs. When we try to put the same key-value pair (“fruit” -> “apple”) again, it is ignored. As a result, only one “apple” value is associated with the “fruit” key, and the output shows just “apple” and “banana” for the “fruit” key. - LinkedListMultimap: The
LinkedListMultimapmaintains the order of insertion. In this case, the keys and values are inserted in the order “banana”, “apple”, and “orange”. As a result, the output reflects this order, with “fruit” mapped to “banana”, “apple”, and “orange”. - TreeMultimap: The
TreeMultimapstores both keys and values in sorted order. When we add the values “banana”, “apple”, and “orange” for the “fruit” key, theTreeMultimapsorts them alphabetically. Thus, the output shows “apple”, “banana”, and “orange” in sorted order.
The code demonstrates the practical use of these different Multimap types to handle multiple values for a single key, with different behaviors depending on the implementation.
The output for each Multimap type is printed to the console:
ArrayListMultimap: {fruit=[apple, apple, banana]}
HashMultimap: {fruit=[apple, banana]}
LinkedListMultimap: {fruit=[banana, apple, orange]}
TreeMultimap: {fruit=[apple, banana, orange]}
3. Iterate Over a Multimap
You can iterate through each key-value pair using multimap.entries(). Alternatively, if you only need to iterate over the keys, use multimap.keySet() and retrieve the associated values for each key. For iterating solely over values, use multimap.values() to access all values independently in the Multimap. Let’s explore this with an example:
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.Map;
public class MultimapIterationExample {
public static void main(String[] args) {
// Create and populate an ArrayListMultimap
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("fruit", "apple");
multimap.put("fruit", "banana");
multimap.put("vegetable", "carrot");
multimap.put("vegetable", "broccoli");
// Iterate over all key-value pairs using entries()
System.out.println("Iterating over all key-value pairs:");
for (Map.Entry<String, String> entry : multimap.entries()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
// Iterate over each key and its associated values using keySet()
System.out.println("\nIterating over each key and associated values:");
for (String key : multimap.keySet()) {
System.out.print("Key: " + key + ", Values: ");
for (String value : multimap.get(key)) {
System.out.print(value + " ");
}
System.out.println();
}
// Iterate over all values only using values()
System.out.println("\nIterating over all values:");
for (String value : multimap.values()) {
System.out.println("Value: " + value);
}
}
}
3.1 Code Explanation and Output
- Using
entries(): Theentries()method provides a flattened view of all key-value pairs as individual entries. In the first loop, we useentries()to iterate over each key-value pair in the multimap. Each entry in the loop is aMap.Entry<String, String>object, which allows us to access both the key and value of each pair directly. - Using
keySet()andget(key): ThekeySet()method returns a set of all unique keys in the multimap. For each key, we retrieve its associated values by callingmultimap.get(key). This returns a collection of values associated with that specific key. In the second loop, we print each key followed by all of its associated values. - Using
values(): Thevalues()method provides a collection of all values in the multimap, without keys. We use this method to iterate over each value individually.
The output of the code is printed to the console:
Iterating over all key-value pairs: Key: fruit, Value: apple Key: fruit, Value: banana Key: vegetable, Value: carrot Key: vegetable, Value: broccoli Iterating over each key and associated values: Key: fruit, Values: apple banana Key: vegetable, Values: carrot broccoli Iterating over all values: Value: apple Value: banana Value: carrot Value: broccoli
4. Compared to the Standard Map
Unlike a standard Map, where each key maps to a single value, Multimap allows each key to map to multiple values. Here’s how they differ:
Map<String, List<String>>requires manual handling to add multiple values per key, whileMultimaphandles this automatically.Multimaphas better readability and more flexibility for many-to-one or many-to-many mappings.
5. Conclusion
The Guava Multimap is a powerful tool for managing key-value relationships where each key may have multiple values. By understanding how to implement and iterate over a Multimap, you can simplify complex mappings and improve code readability.

