Immutable Map Implementations in Java

1. Overview

It is sometimes preferable to disallow modifications to the java.util.Map such as sharing read-only data across threads. For this purpose, we can use either an Unmodifiable Map or an Immutable Map.

In this quick tutorial, we’ll see what’s the difference between them. Then, we’ll present various ways in which we can create an Immutable Map.

2. Unmodifiable vs Immutable

An Unmodifiable Map is just a wrapper over a modifiable map and it doesn’t allow modifications to it directly:

Map<String, String> mutableMap = new HashMap<>();
mutableMap.put("USA", "North America");

Map<String, String> unmodifiableMap = Collections.unmodifiableMap(mutableMap);
assertThrows(UnsupportedOperationException.class,
  () -> unmodifiableMap.put("Canada", "North America"));

But the underlying mutable map can still be changed and the modifications are reflected in the Unmodifiable map as well:

mutableMap.remove("USA");
assertFalse(unmodifiableMap.containsKey("USA"));
		
mutableMap.put("Mexico", "North America");
assertTrue(unmodifiableMap.containsKey("Mexico"));

An Immutable Map, on the other hand, contains its own private data and doesn’t allow modifications to it. Therefore, the data cannot change in any way once an instance of the Immutable Map is created.

3. Guava’s Immutable Map

Guava provides immutable versions of each java.util.Mapusing ImmutableMap. It throws an UnsupportedOperationException whenever we try to modify it.

Since it contains its own private data, this data won’t change when the original map is changed.

We’ll now discuss various ways of creating instances of the ImmutableMap.

3.1. Using copyOf() Method

First, let’s use the ImmutableMap.copyOf() method that returns a copy of all the entries as in the original map:

ImmutableMap<String, String> immutableMap = ImmutableMap.copyOf(mutableMap);
assertTrue(immutableMap.containsKey("USA"));

It cannot be modified directly or indirectly:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));
		
mutableMap.remove("USA");
assertTrue(immutableMap.containsKey("USA"));
		
mutableMap.put("Mexico", "North America");
assertFalse(immutableMap.containsKey("Mexico"));

3.2. Using builder() Method

We can also use ImmutableMap.builder() method to create a copy of all the entries as in the original map.

Moreover, we can use this method to add additional entries that are not present in the original map:

ImmutableMap<String, String> immutableMap = ImmutableMap.<String, String>builder()
  .putAll(mutableMap)
  .put("Costa Rica", "North America")
  .build();
assertTrue(immutableMap.containsKey("USA"));
assertTrue(immutableMap.containsKey("Costa Rica"));

The same as in the previous example, we cannot modify it directly or indirectly:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));
		
mutableMap.remove("USA");
assertTrue(immutableMap.containsKey("USA"));
		
mutableMap.put("Mexico", "North America");
assertFalse(immutableMap.containsKey("Mexico"));

3.3. Using of() Method

Finally, we can use ImmutableMap.of() method to create an immutable map with a set of entries provided on the fly. It supports at most five key/value pairs:

ImmutableMap<String, String> immutableMap
  = ImmutableMap.of("USA", "North America", "Costa Rica", "North America");
assertTrue(immutableMap.containsKey("USA"));
assertTrue(immutableMap.containsKey("Costa Rica"));

We cannot modify it as well:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));

4. Conclusion

In this quick article, we discussed the differences between an Unmodifiable Map and Immutable Map.

We also had a look at different ways of creating Guava’s ImmutableMap.

And, as always, the complete code examples are available over on GitHub.

Related posts:

Java Web Services – Jersey JAX-RS – REST và sử dụng REST API testing tools với Postman
Java Program to Check Whether an Undirected Graph Contains a Eulerian Path
Java Program to Implement Gale Shapley Algorithm
Converting between an Array and a List in Java
Guide to the Synchronized Keyword in Java
Java Program to Implement Attribute API
Java 8 Predicate Chain
Java Program to Implement IdentityHashMap API
Vấn đề Nhà sản xuất (Producer) – Người tiêu dùng (Consumer) và đồng bộ hóa các luồng trong Java
Extra Login Fields with Spring Security
Java Program to Perform Uniform Binary Search
Java Program to Implement Adjacency List
Removing all Nulls from a List in Java
Java – InputStream to Reader
Java Program to Implement CountMinSketch
Java Program to Represent Graph Using Incidence Matrix
Java Program to Solve Tower of Hanoi Problem using Stacks
Spring Security Login Page with React
Java Program to Implement Rope
Spring REST API with Protocol Buffers
Read an Outlook MSG file
So sánh HashMap và HashSet trong Java
Java Program to Implement Word Wrap Problem
Java Program to Perform Inorder Recursive Traversal of a Given Binary Tree
Immutable Objects in Java
Java Program for Topological Sorting in Graphs
Map Interface trong java
Java Program to Find Minimum Element in an Array using Linear Search
Java Program to Use Above Below Primitive to Test Whether Two Lines Intersect
Java Program to Implement Shoelace Algorithm
Java Program to Implement HashMap API
A Guide to Spring Cloud Netflix – Hystrix