Initialize Map in Java

In this post, we will discuss various methods to initialize map in Java.


 

Java is often criticized for its verbosity. For example, creating a map containing involves constructing it, storing it in a variable, invoking put() method on it several times, and then maybe wrapping it to make it unmodifiable:

 

 
In this post, we will discuss various methods to initialize map in a single expression.

 

1. Java Collections –

Collections class consists of several static factory methods that operate on collections and return a new collection backed by a specified collection.

 

1.1. Collections.unmodifiableMap()

Collections class provides unmodifiableMap() method that takes another map and wrap it in a class that rejects modification requests, thus creating an unmodifiable view of the original map. Any attempts to modify the returned map will result in an UnsupportedOperationException.

But it won’t create inherently unmodifiable map. Instead, possession of a reference to the underlying collection still allows modification. Also each wrapper is an additional object, requiring another level of indirection and consuming more memory than the original collection. Finally, the wrapped collection still bears the expense of supporting mutation even if it is never intended to be modified.

 

1.2. Collections.singletonMap()

There are existing factories in the Collections class to produce singleton Map that have exactly one key-value pair.

We can use Collections.singletonMap() that returns an immutable map containing specified key-value pair. The map will throw an UnsupportedOperationException if any modify operation is performed on it.

 

1.3. Collections.emptyMap()

We can use Collections.EMPTY_MAP that returns serializable and immutable empty map.

Above method might throw unchecked assignment warning. Below example illustrates the type-safe way to obtain an empty map:

 

2. Java 8 –

The Java 8 Stream API can be used to construct small maps by obtaining stream from static factory methods like Stream.of() or Arrays.stream() and accumulating the input elements into a new map using collectors.

 

2.1. Collectors.toMap()

A Stream is essentially a sequence of items, not a sequence of key/value pairs. It is illogical to think that we can just take a Stream and construct a Map out of it without specifying how to extract keys and values from it. We can use Collectors.toMap() method to specify it.

Collectors.toMap() returns a Collector that accumulates elements into a Map whose keys and values are the result of applying the provided mapping functions to the input elements.

 
To initialize a map with different types for key and value, for instance Map<String, Integer>, we can do:

 
Another approach which can easily accommodates different types for key and value involves creating a Stream of map entries.

There are two implementations of Map.Entry Interface:

1. AbstractMap.SimpleEntry

 
2. AbstractMap.SimpleImmutableEntry

 

2.2. Collectors.collectingAndThen()

We could also adapt a Collector to perform an additional finishing transformation. For example, we could adapt the toMap() collector to always produce an immutable map with:

 

3. Double Brace Initialization –

Another alternative is to use “Double Brace Initialization”. This creates an anonymous inner class with an instance initializer in it. This technique should be avoided at all costs as it creates an extra class at each usage and it also holds hidden references to the enclosing instance and to any captured objects. This may cause memory leaks or problems with serialization.

 

4. Java 9 –

Read: Initialize Map in Java 9

 

5. Guava –

Read: Initialize Map using Guava Library in Java

 

6. Apache Commons Collections –

Read: Initialize Map using Apache Commons Collections in Java

 
 
Thanks for reading.




Please use ideone or C++ Shell or any other online compiler link to post code in comments.
Like us? Please spread the word and help us grow. Happy coding 🙂
 





Leave a Reply

Notify of
avatar
wpDiscuz