Master Google Guava’s Multimap to Boost Programming Efficiency
This article explains Guava's Multimap feature, covering its core one‑to‑many mapping capabilities, common methods, various implementations (ArrayListMultimap, HashMultimap, LinkedHashMultimap, TreeMultimap, immutable and synchronized versions), and provides concrete Java code examples and a social‑network scenario to help developers choose the right implementation.
Core Features of Multimap
Multimap allows a key to map to multiple values, enabling one‑to‑many relationships such as a user with several email addresses or an order with multiple items. It also supports duplicate values, optional ordering, null keys/values, and provides rich views like asMap(), entries(), and values().
Common Methods
Typical usage requires adding the Guava dependency and importing the classes. Example code shows creating an ArrayListMultimap, adding entries with put and putAll, retrieving values with get, checking existence, removing entries, and using views such as keySet, values, entries, asMap, size, and isEmpty.
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.Map;
public class MultimapExample {
public static void main(String[] args) {
Multimap<String, Integer> multimap = ArrayListMultimap.create();
multimap.put("apple", 1);
multimap.put("apple", 2);
multimap.put("banana", 3);
multimap.put("orange", 4);
multimap.put("orange", 5);
multimap.put("orange", 6);
Map<String, Integer> moreFruits = Map.of("grape", 7, "grape", 8, "kiwi", 9);
multimap.putAll(moreFruits);
System.out.println("Apples: " + multimap.get("apple"));
System.out.println("Contains key 'apple'? " + multimap.containsKey("apple"));
System.out.println("Contains value 6? " + multimap.containsValue(6));
boolean removed = multimap.remove("banana", 3);
System.out.println("Removed banana=3? " + removed);
multimap.removeAll("kiwi");
System.out.println("Kiwis: " + multimap.get("kiwi"));
System.out.println("Unique keys: " + multimap.keySet());
System.out.println("All values: " + multimap.values());
System.out.println("Entries: " + multimap.entries());
System.out.println("As Map: " + multimap.asMap());
System.out.println("Size of multimap: " + multimap.size());
System.out.println("Is multimap empty? " + multimap.isEmpty());
}
}Choosing an Implementation
Guava offers several Multimap implementations, each with different performance and ordering characteristics.
ArrayListMultimap
Preserves insertion order of values and provides constant‑time get operations, but iteration over all entries may be slower in some scenarios.
HashMultimap
Fast key lookup, does not guarantee order, and disallows null keys or values.
LinkedHashMultimap
Combines fast key lookup with insertion‑order preservation, offering a good compromise.
TreeMultimap
Orders keys (and optionally values) using natural ordering or a supplied Comparator, useful for sorted traversals.
ImmutableSetMultimap / ImmutableListMultimap
Immutable variants are thread‑safe and efficient for read‑only scenarios because they cannot be modified after creation.
SynchronizedMultimap
Wraps any Multimap to make it thread‑safe; iteration must be performed inside a synchronized block to avoid concurrency issues.
ForwardingMultimap
Uses the decorator pattern, allowing custom behavior without modifying the underlying implementation. Example shows overriding putAll to log added values.
Practical Example
A simple social‑network simulation demonstrates using different Multimap types to store friends lists (ArrayListMultimap), likes (HashMultimap), messages (LinkedHashMultimap), and activity logs (TreeMultimap). The code adds data, prints collections, and removes a friend to illustrate typical operations.
import com.google.common.collect.*;
import java.util.*;
public class SocialNetwork {
public static void main(String[] args) {
ArrayListMultimap<String, String> friendsByUser = ArrayListMultimap.create();
HashMultimap<String, String> likesByUser = HashMultimap.create();
LinkedHashMultimap<String, String> messagesByUser = LinkedHashMultimap.create();
TreeMultimap<Long, String> activityLog = TreeMultimap.create();
friendsByUser.putAll("Alice", Arrays.asList("Bob", "Charlie", "David"));
friendsByUser.putAll("Bob", Arrays.asList("Alice", "Charlie"));
friendsByUser.put("Charlie", "David");
likesByUser.put("Alice", "Bob's post");
likesByUser.put("Alice", "Charlie's photo");
likesByUser.put("Bob", "Charlie's photo");
likesByUser.putAll("Charlie", Arrays.asList("Alice's status", "David's video"));
messagesByUser.put("Alice", "Hi Bob!");
messagesByUser.put("Alice", "How are you Charlie?");
messagesByUser.put("Bob", "Charlie, where are you?");
messagesByUser.putAll("Charlie", Arrays.asList("Here I am!", "Alice, check this out!"));
activityLog.put(1L, "Alice added a new friend");
activityLog.put(2L, "Bob liked a photo");
activityLog.put(3L, "Charlie sent a message");
System.out.println("Alice's friends: " + friendsByUser.get("Alice"));
for (String user : likesByUser.keys()) {
if (likesByUser.containsEntry(user, "Charlie's photo")) {
System.out.println(user + " liked Charlie's photo");
}
}
for (String message : messagesByUser.get("Alice")) {
System.out.println("Alice said: " + message);
}
for (Map.Entry<Long, String> entry : activityLog.entries()) {
System.out.println("Timestamp: " + entry.getKey() + ", Event: " + entry.getValue());
}
friendsByUser.remove("Alice", "Bob");
System.out.println("Alice's friends after removing Bob: " + friendsByUser.get("Alice"));
}
}When selecting a Multimap, consider whether you need ordering, duplicate values, null handling, immutability, or thread safety, and choose the implementation that best matches those requirements.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer1970
Formerly called 'Code to 35'. Add our main WeChat ID to access a wealth of shared resources (algorithms, interview prep, tech stacks: Java, Python, Go, big data). We mainly share serious development techniques, focusing on output-driven input. Occasionally we post life snippets and gossip. Our aim is to attract precise traffic and test advertising opportunities.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
