Unlock Powerful Map Operations with Guava: Table, BiMap, Multimap, RangeMap & More

This guide explores Guava's extended map utilities—including Table for two‑key maps, BiMap for bidirectional lookups, Multimap for multi‑value mappings, RangeMap for interval‑based keys, and ClassToInstanceMap for type‑safe instance storage—providing code examples, usage tips, and common pitfalls for Java developers.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Unlock Powerful Map Operations with Guava: Table, BiMap, Multimap, RangeMap & More

Guava, a Google‑developed Java library, offers rich APIs that simplify code, add missing JDK features, and improve development efficiency.

Table – Two‑Key Map

In standard Java Map each entry has a single key and value, but Guava's Table allows one value to be associated with two keys (rowKey and columnKey). Example: storing employee work days per month.

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1.1-jre</version>
</dependency>

Traditional nested Map implementation:

Map<String,Map<String,Integer>> map = new HashMap<>();
Map<String,Integer> workMap = new HashMap<>();
workMap.put("Jan",20);
workMap.put("Feb",28);
map.put("Hydra",workMap);
Integer dayCount = map.get("Hydra").get("Jan");

Using Table simplifies the code:

Table<String,String,Integer> table = HashBasedTable.create();
table.put("Hydra","Jan",20);
table.put("Hydra","Feb",28);
Integer dayCount = table.get("Hydra","Feb");

Additional useful operations:

1. Get key or value collections

Set<String> rowKeys = table.rowKeySet();
Set<String> columnKeys = table.columnKeySet();
Collection<Integer> values = table.values();

Row/column key sets contain unique keys, while the value collection includes all values without deduplication.

2. Sum values for each row key

for (String key : table.rowKeySet()) {
    Set<Map.Entry<String,Integer>> rows = table.row(key).entrySet();
    int total = 0;
    for (Map.Entry<String,Integer> row : rows) {
        total += row.getValue();
    }
    System.out.println(key + ": " + total);
}

3. Transpose rows and columns

Table<String,String,Integer> table2 = Tables.transpose(table);
Set<Table.Cell<String,String,Integer>> cells = table2.cellSet();
for (Table.Cell<String,String,Integer> cell : cells) {
    System.out.println(cell.getRowKey()+","+cell.getColumnKey()+":"+cell.getValue());
}

4. Convert to nested Map

Map<String,Map<String,Integer>> rowMap = table.rowMap();
Map<String,Map<String,Integer>> columnMap = table.columnMap();

BiMap – Bidirectional Map

Standard Map requires iteration to find a key by value. Guava's BiMap provides a direct two‑way association.

HashBiMap<String,String> biMap = HashBiMap.create();
biMap.put("Hydra","Programmer");
biMap.put("Tony","IronMan");
System.out.println(biMap.get("Tony")); // IronMan
BiMap<String,String> inverse = biMap.inverse();
System.out.println(inverse.get("Titan")); // Thanos

Important notes:

1. Inverse view shares the same underlying data

HashBiMap<String,String> biMap = HashBiMap.create();
biMap.put("Hydra","Programmer");
BiMap<String,String> inverse = biMap.inverse();
inverse.put("IronMan","Stark");
System.out.println(biMap); // {Hydra=Programmer, Thanos=Titan, Stark=IronMan}

2. Values must be unique

HashBiMap<String,String> biMap = HashBiMap.create();
biMap.put("Tony","IronMan");
biMap.put("Stark","IronMan"); // throws IllegalArgumentException

To replace an existing value, use forcePut:

biMap.forcePut("Stark","IronMan");
System.out.println(biMap); // {Stark=IronMan}

Because values are unique, biMap.values() returns a Set, not a Collection.

Multimap – Multi‑Value Map

Standard Map maps a key to a single value; to associate multiple values, you normally store a collection manually. Guava's Multimap handles this automatically.

Multimap<String,Integer> multimap = ArrayListMultimap.create();
multimap.put("day",1);
multimap.put("day",2);
multimap.put("day",8);
multimap.put("month",3);
System.out.println(multimap); // {month=[3], day=[1, 2, 8]}

1. Retrieve value collections

Collection<Integer> day = multimap.get("day"); // returns a view collection

If the underlying implementation is ArrayListMultimap, get returns a List.

2. Modify the returned collection

ArrayListMultimap<String,Integer> multimap = ArrayListMultimap.create();
multimap.put("day",1);
multimap.put("day",2);
List<Integer> day = multimap.get("day");
day.remove(0); // removes 1 from the original multimap
System.out.println(multimap); // {day=[2]}

3. Convert to Map

Map<String,Collection<Integer>> map = multimap.asMap();
for (String key : map.keySet()) {
    System.out.println(key + " : " + map.get(key));
}
map.get("day").add(20);
System.out.println(multimap); // {day=[1, 2, 8, 20], month=[3]}

4. Size semantics

multimap.size()

returns the total number of key‑value pairs, while multimap.keySet().size() returns the number of distinct keys.

RangeMap – Interval Map

Instead of chained if‑else statements for range checks, Guava's RangeMap maps intervals to values.

RangeMap<Integer,String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closedOpen(0,60),"fail");
rangeMap.put(Range.closed(60,90),"satisfactory");
rangeMap.put(Range.openClosed(90,100),"excellent");
System.out.println(rangeMap.get(59)); // fail
System.out.println(rangeMap.get(60)); // satisfactory
System.out.println(rangeMap.get(90)); // satisfactory
System.out.println(rangeMap.get(91)); // excellent

Ranges can be removed, causing get to return null for points inside the removed interval.

ClassToInstanceMap – Instance Map

This map uses Class objects as keys and stores instances of those classes, providing type‑safe retrieval without explicit casts.

ClassToInstanceMap<Object> instanceMap = MutableClassToInstanceMap.create();
User user = new User("Hydra",18);
Dept dept = new Dept("develop",200);
instanceMap.putInstance(User.class,user);
instanceMap.putInstance(Dept.class,dept);
User user1 = instanceMap.getInstance(User.class);
System.out.println(user == user1); // true

The generic type ensures that values match the class type, preventing accidental type mismatches.

Conclusion

Guava provides five extended map structures— Table, BiMap, Multimap, RangeMap, and ClassToInstanceMap —that greatly simplify common programming tasks, but developers must be aware of view‑backed behavior and uniqueness constraints to avoid subtle bugs.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaGuavaMAPMultimapTableBiMapRangeMap
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.