Signup/Sign In
PUBLISHED ON: AUGUST 7, 2021

Initialize HashMap in Java

A HashMap is used to store key-value pairs. Internally, it uses hashing to store data and fetch data. In this tutorial, we will learn how to initialize a HashMap in Java.

Using the put() method of HashMap

The put() method takes a key and a value as parameters and adds the key-value pair to the HashMap.

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

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> map = new HashMap<>();
		map.put(101, "Justin");
		map.put(102, "Jessica");
		map.put(103, "Simon");
		
		System.out.println(map);
	}
}


{101=Justin, 102=Jessica, 103=Simon}

Note that we can only use this method on mutable maps. If we use this for immutable maps, then we will get the UnsupportedOperationException.

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

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> mutableMap = new HashMap<>();
		mutableMap.put(101, "Justin");
		mutableMap.put(102, "Jessica");
		mutableMap.put(103, "Simon");
		
		Map<Integer, String> immutableMap = Collections.unmodifiableMap(mutableMap); 
		immutableMap.put(104, "Harry");//Error
	}
}


Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1473)
at Demo.main(Demo.java:15)

Creating a Singleton Map

A singleton map is an immutable map that stores a single key-value pair. We will use the Collections.singletonMap() method to initialize it. Since it is an immutable map, we cannot add more than one entry to it. This will result in the UnsupportedOperationException.

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

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> singletonMap =  Collections.singletonMap(101, "Justin");
		System.out.print(singletonMap);
	}
}


{101=Justin}

Creating an Empty Map

We can create an empty, immutable map by using the Collections.emptyMap() method.

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

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> emptyMap =  Collections.emptyMap();
		System.out.print(emptyMap);
	}
}


{}

Creating a Static HashMap

We can create and initialize a static HashMap in Java by using a static block. The following code will create a static mutable map. Note that this approach is not preferred as extra classes are created, unwanted references are stored, and it might cause memory leaks.

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

public class Demo
{
	public static Map<Integer, String> staticMap;
	static
	{
		staticMap = new HashMap<>();
		staticMap.put(101, "Justin");
		staticMap.put(102, "Jessica");
		staticMap.put(103, "Simon");
	}
	public static void main(String[] args)
	{
		System.out.print(staticMap);
	}
}


{101=Justin, 102=Jessica, 103=Simon}

Using the Map.of() Method of Java 9

The Map.of() is a factory method that returns an immutable map with the provided keys and values. A drawback of this method is that we can only add up to 10 entries to the map. We will get a compilation error if we try to add more than 10 key-value pairs.

import java.util.Map;

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> emptyMap = Map.of();
		Map<Integer, String> singletonMap = Map.of(101, "Justin");
		Map<Integer, String> map = Map.of(
				101, "Justin",
				102, "Jessica",
				103, "Simon"
				);
		System.out.println(emptyMap);
		System.out.println(singletonMap);
		System.out.println(map);
	}
}


{}
{101=Justin}
{101=Justin, 102=Jessica, 103=Simon}

Using the Map.ofEntries() Method of Java 9

This method is pretty much the same as the Map.of(). The only difference is that we don't have the restriction of only 10 entries. Just like the Map.of() method, it returns an immutable map.

import java.util.Map;

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> emptyMap = Map.ofEntries();
		Map<Integer, String> singletonMap = Map.ofEntries(Map.entry(101, "Justin"));
		Map<Integer, String> map = Map.ofEntries(
				Map.entry(101, "Justin"),
				Map.entry(102, "Jessica"),
				Map.entry(103, "Simon")
				);
		System.out.println(emptyMap);
		System.out.println(singletonMap);
		System.out.println(map);
	}
}


{}
{101=Justin}
{102=Jessica, 103=Simon, 101=Justin}

Using the Google Guava Library

Guava is a well-known Java library. It provides methods to initialize mutable and immutable maps in Java. To initialize immutable maps, we will use the ImmutableMap.of() method.

import java.util.Map;

import com.google.common.collect.ImmutableMap;

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> map = ImmutableMap.of(
				101, "Justin",
				102, "Jessica",
				103, "Simon"
				);
		System.out.print(map);
	}
}


{101=Justin, 102=Jessica, 103=Simon}

For mutable maps, we will first create an immutable map. Then we will convert it to a mutable HashMap.

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

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

public class Demo
{
	public static void main(String[] args)
	{
		Map<Integer, String> immutableMap = ImmutableMap.of(
				101, "Justin",
				102, "Jessica",
				103, "Simon"
				);
		HashMap<Integer, String> mutableMap = Maps.newHashMap(immutableMap);
		System.out.print(mutableMap);
	}
	
}


{101=Justin, 102=Jessica, 103=Simon}

Using Java Streams for Initializing Maps

The Stream API of Java 8 provides a few different ways to initialize a map. We can create mutable and immutable maps using streams. However, the following techniques of initialization are not recommended as they affect the overall performance of the code and create a lot of garbage objects.

Using Collectors.toMap() Method

We can use a two-dimensional object array(with each row containing a key-value pair) to create a stream. Then, we can collect the streamed objects into our map by using the toMap() method. This will create a mutable map.

import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{	
	public static void main(String[] args)
	{
		Map<Integer, String> map = Stream.of(new Object[][] { 
		     {101, "Justin"}, 
		     {102, "Jessica"},
		     {103, "Simon"}
		 }).collect(Collectors.toMap(data -> (Integer) data[0], data -> (String) data[1]));
		
		System.out.print(map);
	}
}


{101=Justin, 102=Jessica, 103=Simon}

Using SimpleEntry and SimpleImmutableEntry

We can use SimpleEntry to add key-value entries to a map. This will create a mutable map.

import java.util.AbstractMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{	
	public static void main(String[] args)
	{
		Map<Integer, String> map = Stream.of(
				new AbstractMap.SimpleEntry<>(101, "Justin"),
				new AbstractMap.SimpleEntry<>(102, "Jessica"),
				new AbstractMap.SimpleEntry<>(103, "Simon")
		 ).collect(Collectors.toMap(
				 Map.Entry::getKey,  
				 Map.Entry::getValue));

		System.out.print(map);
		
	}
}


{101=Justin, 102=Jessica, 103=Simon}

Similarly, we can use the SimpleImmutableEntry. This approach will also create a mutable map.

import java.util.AbstractMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{	
	public static void main(String[] args)
	{
		Map<Integer, String> map = Stream.of(
				new AbstractMap.SimpleImmutableEntry<>(101, "Justin"),
				new AbstractMap.SimpleImmutableEntry<>(102, "Jessica"),
				new AbstractMap.SimpleImmutableEntry<>(103, "Simon")
		 ).collect(Collectors.toMap(
				 Map.Entry::getKey,  
				 Map.Entry::getValue));
		
		System.out.print(map);
		
		
	}
}


{101=Justin, 102=Jessica, 103=Simon}

Initializing Immutable Maps Using Streams

The approaches discussed above will create a mutable map. But we can also use Java streams to create immutable maps. This is done by using Collectors.collectingAndThen().

import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo
{	
	public static void main(String[] args)
	{
		Map<Integer, String> immutableMap = Stream.of(new Object[][] { 
	    {101, "Justin"}, 
	    {102, "Jessica"},
	    {103, "Simon"}
	}).collect(Collectors.collectingAndThen(
	    Collectors.toMap(data -> (Integer) data[0], data -> (String)data[1]), 
	    Collections::<Integer, String> unmodifiableMap));
		
		System.out.println(immutableMap);
		
		immutableMap.put(104, "Harry");//Error
	}
}


{101=Justin, 102=Jessica, 103=Simon}
Exception in thread "main" java.lang.UnsupportedOperationException
at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1473)
at Demo.main(Demo.java:20)

Summary

Maps in Java are initialized in a lot of different ways. The simplest way of initializing HashMaps is to use the put() method. But we cannot use this for initializing immutable maps. We can use the Map.of() and the Map.ofEntries() methods to create immutable maps. Streams are also used to create mutable and immutable maps, but they degrade the performance.



About the author:
I am a 3rd-year Computer Science Engineering student at Vellore Institute of Technology. I like to play around with new technologies and love to code.