This post will discuss about Map.of() and Map.ofEntries() methods in Java.

1. Using Map.of() method

Java 9 made it very convenient to create instances of the map by providing static factory methods on the Map interface that creates a compact, unmodifiable instance of Map. For example, the Map.of() method allows us to create an immutable map with up to 10 key-value pairs. The syntax is:

Map.of()          // creates an empty map
Map.of(k1, v1)    // creates a singleton map
Map.of(k1, v1, k2, v2)
Map.of(k1, v1, k2, v2, k3, v3)

Map.of(k1, v1, k2, v2, k3, v3, …, k10, v10)

Here, k is the type of keys and v is the type of values. The resulting map will be an immutable map, which means that we cannot modify it by adding, removing, or updating its elements. If we try to do so, we will get an UnsupportedOperationException. For example, to create an immutable map of countries and continents, we can write:

Download  Run Code

2. Using Map.ofEntries() method

There is a no var-args overload of Map.of() which can handle any number of mappings. To create an immutable map with an arbitrary number of entries, we can use Map.ofEntries() method with Map.Entry objects as arguments. It includes varargs overloads, so there is no fixed limit on the map size. This method requires each key-value pair to be boxed. We can use the Map.entry() method to create a Map.Entry object from a key and a value. Here’s the syntax:

Map.ofEntries(
  entry(k1, v1),
  entry(k2, v2),
  entry(k3, v3),
  // …
  entry(kn, vn)
);

Like before, the resulting map will be an immutable map, which means we will get an UnsupportedOperationException if we try to do modify it. For example, to create an immutable map of fruits and their colors, we can write:

Download  Run Code

 
The main difference between Map.of() and Map.ofEntries() methods is that Map.of() takes a fixed number of key-value pairs as arguments, while Map.ofEntries() takes a variable number of Map.Entry objects as arguments. Both these methods return an instance of the Map interface, and not a specific implementation class. Therefore, we should not make any assumptions about the identity or performance of the returned maps.

3. Characteristics of Map.of() and Map.ofEntries() methods

The map instances created by the Map.of() and Map.ofEntries() methods have the following characteristics:

  1. They are structurally immutable. Keys and values cannot be added, removed, or updated. Any attempt to do so will throw an UnsupportedOperationException. However, if the contained keys or values are mutable, this may cause the map to behave inconsistently, or its contents appear to change.
  2. They do not allow null keys or values. Any attempt to use a null key or value will throw a NullPointerException.
  3. They are serializable if all keys and values are serializable.
  4. If we pass duplicate keys to a static factory method, they will not be accepted when the map is created. An IllegalArgumentException will be thrown instead.
  5. They have an unspecified iteration order of the mappings, which may change across different implementations or invocations.
  6. The returned instances are based on their values, not their identities. Callers should not expect that the same instance will be returned every time. Factories can either create new instances or use existing ones. So, operations that depend on the identity of the instances (such as reference equality (==), getting their identity hash code, or synchronizing them) are not trustworthy and should not be used.
  7. They are optimized for performance and memory usage, depending on the number and type of the key-value pairs.

4. Create a Mutable Copy

To create a mutable map from the immutable map, we can use a constructor or a copy method of a concrete map implementation, such as HashMap or LinkedHashMap. For instance:

Download  Run Code

Also note that static factory methods on concrete collection classes such as HashMap are not included in Java 9. Since static methods on interfaces are not inherited, it will not be possible to invoke them via an implementing class nor an instance of the interface type.

 
Reference: JEP 269: Convenience Factory Methods for Collections