Tuesday 19 July 2022

How to get unmodifiable view of a Map in Java?

Collections.unmodifiableMap method return unmodifiable view of the a map.

 

Signature

public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m)

Example

Map<Integer, Integer> unmodifiablePrimesMap = Collections.unmodifiableMap(primesMap);

What will happen when I try to modify the unmodifiable map?

Any attempt to modify the unmodifiable map, whether direct or via its iterator, result in an UnsupportedOperationException.

 

In brief, following operations throw UnsupportedOperationException on unmodifiable map.

 

a.   put

b.   remove

c.    putAll

d.   putAll

e.   replaceAll

f.     putIfAbsent

g.   remove

h.   replace

i.     computeIfAbsent

j.     computeIfPresent

k.    compute

l.     merge


UnmodifiableViewOfAMap.java

package com.sample.app.collections;

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

public class UnmodifiableViewOfAMap {

	public static void main(String[] args) {
		Map<Integer, Integer> primesMap = new HashMap<>();

		primesMap.put(1, 2);
		primesMap.put(2, 3);
		primesMap.put(3, 5);
		primesMap.put(4, 7);

		Map<Integer, Integer> unmodifiablePrimesMap = Collections.unmodifiableMap(primesMap);

		try {
			unmodifiablePrimesMap.put(5, 11);
		} catch (Exception e) {
			System.err.println("\nError while performing put operation : ");
			e.printStackTrace();
		}

	}

}

Output

Error while performing put operation : 
java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
	at com.sample.app.collections.UnmodifiableViewOfAMap.main(UnmodifiableViewOfAMap.java:20)

Note

Unless all the elements in the map are immutable, unmodifiable map is not completely safe, because while map might be unmodifiable, but the elements may be themselves modified.

 

For example, if Employee class is mutable, below snippet transform employee names to uppercase.

 

unmodifiableMap.forEach((id, emp) -> {
	emp.name = emp.name.toUpperCase();
});

Find the below working application.

 

UnmodifiableViewOfAMap1.java

package com.sample.app.collections;

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

import org.apache.commons.collections.map.HashedMap;

public class UnmodifiableViewOfAMap1 {
	private static class Employee {
		private Integer id;
		private String name;

		public Employee(Integer id, String name) {
			this.id = id;
			this.name = name;
		}

		@Override
		public String toString() {
			return "Employee [id=" + id + ", name=" + name + "]";
		}

	}

	public static void main(String[] args) {

		Map<Integer, Employee> map = new HashedMap() {
			{
				put(1, new Employee(1, "Ram"));
				put(2, new Employee(2, "Krishna"));
				put(3, new Employee(3, "Jaideep"));
			}
		};

		Map<Integer, Employee> unmodifiableMap = Collections.unmodifiableMap(map);

		System.out.println(unmodifiableMap);

		unmodifiableMap.forEach((id, emp) -> {
			emp.name = emp.name.toUpperCase();
		});

		System.out.println(unmodifiableMap);

	}

}

Output

{2=Employee [id=2, name=Krishna], 1=Employee [id=1, name=Ram], 3=Employee [id=3, name=Jaideep]}
{2=Employee [id=2, name=KRISHNA], 1=Employee [id=1, name=RAM], 3=Employee [id=3, name=JAIDEEP]}




 

 

  

Previous                                                 Next                                                 Home

No comments:

Post a Comment