Explain Codes LogoExplain Codes Logo

Initializing a Guava ImmutableMap

java
immutablemap
builder
performance
Alex KataevbyAlex KataevยทAug 9, 2024
โšกTLDR

For a quick setup of a Guava ImmutableMap with up to 5 entries, give ImmutableMap.of a shot:

// "a" and "1" sitting in a tree... ImmutableMap<String, Integer> map = ImmutableMap.of("a", 1, "b", 2);

In cases where you're dealing with a regularly fed gorilla ๐Ÿฆ (a.k.a. larger maps), get ready for ImmutableMap.Builder:

// You know something is big when even Java runs out of breath... ImmutableMap<String, Integer> largeMap = ImmutableMap.builder() .put("a", 1).put("b", 2).put("c", 3).put("d", 4).build();

To clone an existing map as an immutable copy without a nanobot swarm, use ImmutableMap.copyOf:

// Everyone needs a twin, even maps! ImmutableMap<String, Integer> copyOfMap = ImmutableMap.copyOf(existingMap);

For conciseness, go with .of(). For a slightly longer breath, pick builder() then .put().build() to end it.

Choosing the right method

of() vs builder()

When to choose of() over builder() or vice versa? It's not a versus battle, but about weighing ease of use and flexibility:

  • ImmutableMap.of(): Quick to use, but fits only up to 5 key-value pairs. Use for small static datasets.
  • ImmutableMap.builder(): Flexible, scales nicely. Got more than a handful pairs? Time for builder().

Adding multiple entries

Adding more pairs? Cake walk! Make use of the putAll() method to feed the builder with a collection:

// "Let them eat collection!", said Builder before the revolution Map<String, Integer> sourceMap = // ... ImmutableMap<String, Integer> guavaMap = ImmutableMap.builder() .putAll(sourceMap).build();

Balancing capability and readability

It's all about that delicate balance. Combine of() and builder() in a graceful dance for not only advanced capabilities, but also clear readability in larger datasets.

Advantages and use cases of ImmutableMap

Short and sweet advantages

ImmutableMap is a poster child for safety and simplicity in Java:

  • Simplicity: Immutable objects are simple and safe, less bugs related to mutable state.
  • Performance: Leveraging immutability can kickstart Java's performance optimizations.
  • Consistency: Expect predictable behavior in concurrent environments by enforcing immutability.

Handling complex data structures

A few scenarios to illustrate the versatility of ImmutableMap.Builder:

Nested ImmutableMaps

Nested structures? Child's play! Here's calling keys for another map:

// Inception alert! We have a map within a map! ImmutableMap<String, ImmutableMap<String, String>> nestedMap = new ImmutableMap.Builder<String, ImmutableMap<String, String>>() .put("US", ImmutableMap.of("NY", "New York")) .put("Canada", ImmutableMap.of("ON", "Ontario")) .build();

ImmutableMap of lists

Mapping keys to lists? No problem! ImmutableList to the rescue:

// A list so prestigious, even lists want an autograph. ImmutableMap<String, ImmutableList<String>> citiesMap = ImmutableMap.builder() .put("USA", ImmutableList.of("New York", "San Francisco")) .put("Canada", ImmutableList.of("Toronto", "Vancouver")) .build();