Coding in the small with Google Collections: Multimap
Part 9 in a Series by Robert Konigsberg, Guest blogger...Multimap is like a Map, but lets you store multiple values for every key. It turns out this is frequently useful. Consider how often you have had to create, for instance, a Map<K, List<V>>.
Before:
Map<Salesperson, List<Sale>> map = new Hashmap<SalesPerson, List<Sale>>();
public void makeSale(Salesperson salesPerson, Sale sale) {
List<Sale> sales = map.get(salesPerson);
if (sales == null) {
sales = new ArrayList<Sale>();
map.put(salesPerson, sales);
}
sales.add(sale);
}
After:
Multimap<Salesperson, Sale> multimap
= new ArrayListMultimap<Salesperson,Sale>();
public void makeSale(Salesperson salesPerson, Sale sale) {
multimap.put(salesperson, sale);
}
This is just one facet of Multimaps. Consider finding the largest value across all keys:
Before:
public Sale getBiggestSale() {
Sale biggestSale = null;
for (List<Sale> sales : map.values()) {
Sale biggestSaleForSalesman
= Collections.max(sales, SALE_COST_COMPARATOR);
if (biggestSale == null
|| biggestSaleForSalesman.getCharge() > biggestSale().getCharge()) {
biggestSale = biggestSaleForSalesman;
}
}
return biggestSale;
}
After:
public Sale getBiggestSale() {
return Collections.max(multimap.values(), SALE_COST_COMPARATOR);
}
The Google Collections Library comes with a large variety of Multimap implementations that you can choose from to meet your specific performance characteristics. Do you want to prevent duplicate key/value pairs? Use HashMultimap. Do you want to iterate over the maps in insertion-order? Use LinkedHashMultimap. Do you want the keys and values ordered by their natural ordering? Use TreeMultimap.
Don't forget to read the Javadoc for Multimaps, which provides access to all the supplied implementations, and much more.
Part 10