September 6, 2022

Java Immutable Map With Examples

In Java 9 new static factory method has been added to create an immutable Map in Java. In this article we’ll see an example of creating immutable Map using factory method and how it makes it more convenient than the previous option of using Collections.unmodifiableMap().

You can not remove or add elements from an immutable Map. Calling any mutator method on the Map will always cause UnsupportedOperationException to be thrown.

Creating immutable or unmodifiable Map before Java 9

Before Java 9, Collections.unmodifiableMap() method was used to create an immutable Map. One thing to note with this method is that original Map can still be modified.

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class ImmutMap {
  public static void main(String[] args) {
    Map<String, String> numMap = new HashMap<String, String>();
    numMap.put("1", "One");
    numMap.put("2", "Two");
    numMap.put("3", "Three");
    numMap.put("4", "Four");
    Map<String, String> iMap = Collections.unmodifiableMap(numMap);
    // Original map can be changed
    numMap.put("5", "Five");
    System.out.println("numMap" + numMap);
    //Throws exception as this Map is an unmodifiable view
    iMap.put("6", "Six");
  }
}
Output
numMap{1=One, 2=Two, 3=Three, 4=Four, 5=Five}
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1455)
	at com.knpcode.proj.Programs.ImmutMap.main(ImmutMap.java:19)

As you can see from the output numMap, which is the original map, can still be modified (a new pair is added) but the immutable map can’t be modified.

Creating Immutable Map Java 9 onward

Java 9 onward there are following static factory methods providing a convenient way to create unmodifiable maps.

  1. Map.of() (Added in Java 9)
  2. Map.ofEntries() (Added in Java 9)
  3. Map.copyOf() (Added in Java 10)

The Map instances created by these methods have the following characteristics:

  • These methods create unmodifiable maps. Keys and values cannot be added, removed, or updated. Calling any mutator method on the Map will always cause UnsupportedOperationException to be thrown. However, if the contained keys or values are themselves mutable, this may cause the Map to behave inconsistently or its contents to appear to change.
  • Null keys and values are not permitted. Attempts to create them with null keys or values result in NullPointerException.
  • They are serializable if all keys and values are serializable.
  • They reject duplicate keys at creation time. Duplicate keys passed to a static factory method result in IllegalArgumentException.
  • The iteration order of mappings is unspecified and is subject to change.
Map.of() method example

This method is overloaded and 0 to 10 elements can be passed.

of()- Returns an unmodifiable map containing zero mappings.
of(K k1, V v1)- Returns an unmodifiable map containing a single mapping.
of(K k1, V v1, K k2, V v2)- Returns an unmodifiable map containing two mappings.
..
..
of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9)- Returns an unmodifiable map containing nine mappings.
of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)- Returns an unmodifiable map containing ten mappings.
public class ImmutMap {
  public static void main(String[] args) {
    Map<String, String> numMap = Map.of("1", "One", 
              "2", "Two",
              "3", "Three",
              "4", "Four");

    System.out.println("numMap" + numMap);
    //Throws exception no change in Immutable Map
    numMap.put("5", "Five");
  }
}
Output
numMap{3=Three, 4=Four, 1=One, 2=Two}
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:72)
	at java.base/java.util.ImmutableCollections$AbstractImmutableMap.put(ImmutableCollections.java:731)
	at com.knpcode.proj.Programs.ImmutMap.main(ImmutMap.java:15)
Java Map.ofEntries() method

If you have more than 10 key-value pairs, then create the map entries using the Map.entry method, and pass those objects to the Map.ofEntries method. This method returns an unmodifiable map containing keys and values extracted from the given entries.

public class ImmutMap {
  public static void main(String[] args) {
    Map<String, String> numMap = Map.ofEntries(entry("1", "One"), 
              entry("2", "Two"),
              entry("3", "Three"),
              entry("4", "Four"));

    System.out.println("numMap" + numMap);
  }
}
Output
numMap{3=Three, 2=Two, 1=One, 4=Four}
Map.copyOf() method example

If you want to create an immutable Map from a given Map you can use copyOf() method. The given Map must not be null, and it must not contain any null keys or values. If the given Map is subsequently modified, the returned Map will not reflect such modifications.

public class ImmutMap {
  public static void main(String[] args) {
    Map<String, String> numMap = new HashMap<String, String>();
    numMap.put("1", "One");
    numMap.put("2", "Two");
    numMap.put("3", "Three");
    numMap.put("4", "Four");

    System.out.println("numMap- " + numMap);
    Map<String, String> iMap = Map.copyOf(numMap);
    System.out.println("iMap- " + iMap);

    numMap.put("5", "Five");
    System.out.println("numMap after modification- " + numMap);
    System.out.println("iMap- " + iMap);
  }
}
Output
numMap- {1=One, 2=Two, 3=Three, 4=Four}
iMap- {3=Three, 2=Two, 1=One, 4=Four}
numMap after modification- {1=One, 2=Two, 3=Three, 4=Four, 5=Five}
iMap- {3=Three, 2=Two, 1=One, 4=Four}

As you can see the original map which is copied to create the immutable map can be modified but that change doesn’t reflect in the immutable Map.

That's all for the topic Java Immutable Map With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment