- ImmutableMap, as suggested by the name, is a type of Map which is immutable. It means that the content of the map are fixed or constant after declaration, that is, they are read-only.
- If any attempt made to add, delete and update elements in the Map, UnsupportedOperationException is thrown.
- An ImmutableMap does not allow null element either.
- If any attempt made to create an ImmutableMap with null element, NullPointerException is thrown. If any attempt is made to add null element in Map, UnsupportedOperationException is thrown.
Advantages of ImmutableMap
- They are thread safe.
- They are memory efficient.
- Since they are immutable, hence they can be passed over to third party libraries without any problem.
Note that it is an immutable collection, not collection of immutable objects, so the objects inside it can be modified.
Class Declaration:
@GwtCompatible(serializable=true,
emulated=true)
public abstract class ImmutableMap
extends Object
implements Map, Serializable
Class hierarchy:
java.lang.Object
↳ com.google.common.collect.ImmutableMap
Creating ImmutableMap ImmutableMap can be created by various methods. These include:
- From existing Map using copyOf() function of Guava
Java
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
class MapUtil {
public static <K, T> void iMap(Map<K, T> map)
{
ImmutableMap<K, T> immutableMap = ImmutableMap.copyOf(map);
System.out.println(immutableMap);
}
public static void main(String[] args)
{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put( 1 , "Geeks");
map.put( 2 , "For");
map.put( 3 , "Geeks");
iMap(map);
}
}
|
- Output:
{1=Geeks, 2=For, 3=Geeks}
- New ImmutableMap using of() function from Guava
Java
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;
class MapUtil {
public static void createImmutableMap()
{
ImmutableMap<Integer, String> immutableMap = ImmutableMap.of(
1 , "Geeks",
2 , "For",
3 , "Geeks");
System.out.println(immutableMap);
}
public static void main(String[] args)
{
createImmutableMap();
}
}
|
- Output:
{1=Geeks, 2=For, 3=Geeks}
- Using Java 9 Factory Of() method In Java, use of() with Set, Map or List to create an Immutable Map. Please Note: The programs below are of Java 9. Hence you would need a Java 9 compiler to run them.
Java
import java.util.*;
import com.google.common.collect.ImmutableMap;
class GfG {
public static void main(String args[])
{
Map<Integer, String> map = Map.of(
1 , "Geeks",
2 , "For",
3 , "Geeks");
System.out.println(map);
}
}
|
- Output:
{1=Geeks, 2=For, 3=Geeks}
- Using Builder() from ImmutableMap In Guava, ImmutableMap class provides a function Builder(). Through this function, a new ImmutableMap can be created, or an ImmutableMap can be created from an existing Map or both.
- Creating a new ImmutableMap
Java
import java.util.*;
import com.google.common.collect.ImmutableMap;
class GfG {
public static void main(String args[])
{
ImmutableMap<Integer, String> imap =
ImmutableMap.<Integer, String>builder()
.put( 1 , "Geeks")
.put( 2 , "For")
.put( 3 , "Geeks")
.build();
System.out.println(imap);
}
}
|
{1=Geeks, 2=For, 3=Geeks}
- Creating an ImmutableMap from existing Map
Java
import java.util.*;
import com.google.common.collect.ImmutableMap;
class GfG {
public static void main(String args[])
{
Map<Integer, String> map = Map.of( 1 , "Geeks",
2 , "For",
3 , "Geeks");
ImmutableMap<Integer, String> imap =
ImmutableMap.<Integer, String>builder()
.putAll(map)
.build();
System.out.println(imap);
}
}
|
{1=Geeks, 2=For, 3=Geeks}
- Creating a new ImmutableMap including the existing Map
Java
import java.util.*;
import com.google.common.collect.ImmutableMap;
class GfG {
public static void main(String args[])
{
Map<Integer, String> map = Map.of( 1 , "Geeks",
2 , "For",
3 , "Geeks");
ImmutableMap<Integer, String> imap =
ImmutableMap.<Integer, String>builder()
.putAll(map)
.put( 4 , "Computer")
.put( 5 , "Portal")
.build();
System.out.println(imap);
}
}
|
{1=Geeks, 2=For, 3=Geeks, 4=Computer, 5=Portal}
Try to change ImmutableMap As mentioned earlier, the below program will throw UnsupportedOperationException.
Java
import java.util.*;
class GfG {
public static void main(String args[])
{
Map<Integer, String> map = Map.of();
map.put( 1 , "Geeks");
map.put( 2 , "For");
map.put( 3 , "Geeks");
}
}
|
Output :
Exception in thread "main" java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218)
at ImmutableListDemo.main(Main.java:16)
How is it different from Collections.unmodifiableMap()? Collections.unmodifiableMap creates a wrapper around the same existing Map such that the wrapper cannot be used to modify it. However we can still change original Map.
Java
import java.io.*;
import java.util.*;
class GFG {
public static void main(String[] args)
{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put( 1 , "Geeks");
map.put( 2 , "For");
map.put( 3 , "Geeks");
Map<Integer, String> imap = Collections.unmodifiableMap(map);
map.put( 4 , "Computer");
map.put( 5 , "Portal");
System.out.println(imap);
}
}
|
Output:
{1=Geeks, 2=For, 3=Geeks, 4=Computer, 5=Portal}
If we create an ImmutableMap from an existing Map and change the existing Map, the ImmutableMap does not change because a copy is created.
Java
import java.io.*;
import java.util.*;
import com.google.common.collect.ImmutableMap;
class GFG {
public static void main(String[] args)
{
Map<Integer, String> map = new HashMap<Integer, String>();
map.put( 1 , "Geeks");
map.put( 2 , "For");
map.put( 3 , "Geeks");
ImmutableMap<Integer, String> imap = ImmutableMap.copyOf(map);
map.put( 4 , "Computer");
map.put( 5 , "Portal");
System.out.println(imap);
}
}
|
Output :
{1=Geeks, 2=For, 3=Geeks}
Another approach:
1) Using Collections.singletonMap()
Description: The Collections.singletonMap() method returns an immutable map containing only one mapping. It is used to create a map with a single key-value pair.
Syntax:
Collections.singletonMap(key, value)
Example:
Java
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class SingletonMapDemo {
public static void main(String[] args)
{
Map<String, Integer> map
= Collections.singletonMap( "gfg" , 25 );
System.out.println(map);
}
}
|
Note: This will throw an UnsupportedOperationException because the map is immutable