Java Map.of() and Map.ofEntries() Example

By Arvind Rai, February 03, 2020
The Map.of and Map.ofEntries are static factory methods that return unmodifiable Map containing specified mapping. The Map.of and Map.ofEntries are the static factory methods of java.util.Map and has been introduced in Java 9.
1. The unmodifiable Map cannot add, delete element and we can also not update the reference of key and value but we can change the values of these objects. The unmodifiable Map and immutable Map are not same. An unmodifiable Map containing immutable objects is called immutable Map. An immutable Map is automatically thread-safe. It consumes less memory and performs faster.
2. The Map.of and Map.ofEntries methods create unmodifiable Map. After its creation, the keys and values cannot be added, deleted and updated and if we try to these operation, UnsupportedOperationException will be thrown. The object reference of key and value cannot be changed but their values can be changed if they are not immutable. In an immutable Map, we cannot change anything.
3. The unmodifiable Map disallow null keys and values. They will be serializable if keys and values are serializable. They do not accept duplicate keys. The iteration order is not fixed, it may change.
4. The Map.of and Map.ofEntries methods are different from Collections.unmodifiableMap method. The unmodifiable Map returned by Collections.unmodifiableMap, is a wrapper on source Map and if source Map goes to change, the unmodifiable Map will also change.

Map.of

The Map.of returns unmodifiable Map. We need to pass key and value pairs. The number of key and value pairs that can be passed are from 0 to 10. Find the method signature of Map.of for some key and value pairs.
static <K,​V> Map<K,​V> of​(K k1, V v1)
static <K,​V> Map<K,​V> of​(K k1, V v1, K k2, V v2)
static <K,​V> Map<K,​V> of​(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) 
In this way there can be up to k10, v10 in the arguments. Now we will discuss some examples.
Example-1: The Java wrapper classes for all the primitive data types are immutable. Find the examples to create immutable Map with key of integer type and value of string type.
MapOf1.java
import java.util.Map;
public class MapOf1 {
  public static void main(String[] args) {
	Map<Integer, String> map = Map.of(101, "PP", 102, "QQ", 103, "RR");
	map.forEach((k, v) -> System.out.println(k + " - " + v));
  }
} 
Try to put element in immutable Map.
map.put(104, "SS"); 
We will get error.
Exception in thread "main" java.lang.UnsupportedOperationException 

Example-2: Here we will create immutable Map with immutable List.
MapOf2.java
import java.util.List;
import java.util.Map;
public class MapOf2 {
  public static void main(String[] args) {
	List<String> imtList1 = List.of("P1", "Q1");
	List<String> imtList2 = List.of("P2", "Q2");	
	
	Map<Integer, List<String>> map = Map.of(111, imtList1, 222, imtList2);
	System.out.println(map);
  }
} 
If we don't use immutable List as value, then the unmodifiable Map with mutable List will also not be immutable. Find the demo.
MapOf3.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MapOf3 {
  public static void main(String[] args) {
	List<String> list1 = new ArrayList<>();
	list1.add("P1");
	list1.add("Q1");	
	List<String> list2 = new ArrayList<>();
	list2.add("P2");
	list2.add("Q2");	
	
	Map<Integer, List<String>> map = Map.of(111, list1, 222, list2);
	System.out.println(map);
	
	list1.add("R1");
	System.out.println(map);	
  }
} 
Output
{111=[P1, Q1], 222=[P2, Q2]}
{111=[P1, Q1, R1], 222=[P2, Q2]} 

Example-3: Find immutable Map with custom immutable class.
MapOf4.java
import java.util.Map;
public class MapOf4 {
  public static void main(String[] args) {
	Student s1 = new Student(24, "Mahesh");
	Student s2 = new Student(25, "Suresh");

	Map<String, Student> map = Map.of("one", s1, "two", s2);
	map.forEach((k, v) -> System.out.println(k + " - " + v.getName()));
  }
} 
Student.java
public final class Student {
  final private int age;  
  final private String name;
  public Student(final int age, final String name) {
      this.age = age;
      this.name = name;
  }
  public int getAge() {
    return age;
  }

  public String getName() {
    return name;
  }
} 

Map.ofEntries

The Map.ofEntries returns unmodifiable Map containing keys and values extracted from the given entries. Find its declaration.
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries) 
To create Map.Entry, Java 9 Map has entry method as following.
static <K,V> Map.Entry<K,V> entry(K k, V v) 
Where k is key and v is value of the Map.
Example-1: Find the examples to create immutable Map with key of integer type and value of string type.
MapOfEntries1.java
import static java.util.Map.entry;
import java.util.Map;
public class MapOfEntries1 {
  public static void main(String[] args) {
	Map<Integer, String> map = Map.ofEntries(
		entry(101, "PP"),
		entry(102, "QQ"),
		entry(103, "RR")
	);
	map.forEach((k, v) -> System.out.println(k + " - " + v));
  }
} 
Try to put element in immutable Map.
map.put(104, "SS"); 
We will get error.
Exception in thread "main" java.lang.UnsupportedOperationException 

Example-2: Here we will create immutable Map with immutable List.
MapOfEntries2.java
import static java.util.Map.entry;
import java.util.List;
import java.util.Map;

public class MapOfEntries2 {
  public static void main(String[] args) {
	List<String> imtList1 = List.of("P1", "Q1");
	List<String> imtList2 = List.of("P2", "Q2");	
	
	Map<Integer, List<String>> map = Map.ofEntries(
		entry(111, imtList1),
		entry(222, imtList2)
	);
	System.out.println(map);
  }
} 
If we don't use immutable List as value, then the unmodifiable Map with mutable List will also not be immutable. Find the example.
MapOfEntries3.java
import static java.util.Map.entry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MapOfEntries3 {
  public static void main(String[] args) {
	List<String> list1 = new ArrayList<>();
	list1.add("P1");
	list1.add("Q1");	
	List<String> list2 = new ArrayList<>();
	list2.add("P2");
	list2.add("Q2");	

	Map<Integer, List<String>> map = Map.ofEntries(
		entry(111, list1),
		entry(222, list2)
	);
	System.out.println(map);
	
	list1.add("R1");
	System.out.println(map);	
  }
} 
Output
{222=[P2, Q2], 111=[P1, Q1]}
{222=[P2, Q2], 111=[P1, Q1, R1]} 

Example-3: Find immutable Map with custom immutable Student class.
MapOfEntries4.java
import static java.util.Map.entry;
import java.util.Map;
public class MapOfEntries4 {
  public static void main(String[] args) {
	Student s1 = new Student(24, "Mahesh");
	Student s2 = new Student(25, "Suresh");
	
	Map<String, Student> map = Map.ofEntries(
		entry("one", s1),
		entry("two", s2)
	);
	map.forEach((k, v) -> System.out.println(k + " - " + v.getName()));
  }
} 

Unmodifiable Map by Collections.unmodifiableMap()

The unmodifiable Map created by Map.of and Map.ofEntries is different from unmodifiable Map returned by Collections.unmodifiableMap() . The difference is that Collections.unmodifiableMap() returns an unmodifiable view of the specified Map. If we perform add, update or delete operation on source Map specified to Collections.unmodifiableMap() then the unmodifiable Map returned by this method will also change.
UnmodifiableMapTest.java
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class UnmodifiableMapTest {
  public static void main(String[] args) {
	Map<Integer, String> map = new HashMap<>();
	map.put(101, "AA");
	map.put(102, "BB");	
	
	Map<Integer, String> unmodMap = Collections.unmodifiableMap(map);
	System.out.println(unmodMap);
	
	map.put(103, "CC");	
	System.out.println(unmodMap);
  }
} 
Output
{101=AA, 102=BB}
{101=AA, 102=BB, 103=CC} 

References

Java doc: Map
Creating Immutable Maps
POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us