Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 4535

Immutable Map Implementations in Java

$
0
0

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.Map using 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.


Viewing all articles
Browse latest Browse all 4535

Trending Articles