Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnmodifiableMap (Java Collections) vs ImmutableMap (Google) [duplicate]

Context

I need to return a reference to a map that I'm using for a data cache, and I'd like to make sure nobody can modify their reference.

Question

I've seen lots of references to UnmodifiableMap and ImmutableMap online, but I don't see anything comparing/contrasting them. I figure there is a good reason that Google/Guava created their own version - can someone tell me what it is?

like image 857
John Humphreys Avatar asked Mar 25 '14 13:03

John Humphreys


People also ask

Is map immutable in Java?

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.

What is Unmodifiable collection in Java?

An unmodifiable collection is often a copy of a modifiable collection which guarantees that the collection itself cannot be altered. Attempts to modify it will result in an UnsupportedOperationException exception. It is important to notice that objects which are present inside the collection can still be altered.

Is HashMap immutable?

Immutabiility is required, in order to prevent changes on fields used to calculate hashCode() because if key object return different hashCode during insertion and retrieval than it won't be possible to get object from HashMap.


4 Answers

An unmodifiable map may still change. It is only a view on a modifiable map, and changes in the backing map will be visible through the unmodifiable map. The unmodifiable map only prevents modifications for those who only have the reference to the unmodifiable view:

Map<String, String> realMap = new HashMap<String, String>(); realMap.put("A", "B");  Map<String, String> unmodifiableMap = Collections.unmodifiableMap(realMap);  // This is not possible: It would throw an  // UnsupportedOperationException //unmodifiableMap.put("C", "D");  // This is still possible: realMap.put("E", "F");  // The change in the "realMap" is now also visible // in the "unmodifiableMap". So the unmodifiableMap // has changed after it has been created. unmodifiableMap.get("E"); // Will return "F".  

In contrast to that, the ImmutableMap of Guava is really immutable: It is a true copy of a given map, and nobody may modify this ImmutableMap in any way.

Update:

As pointed out in a comment, an immutable map can also be created with the standard API using

Map<String, String> immutableMap =      Collections.unmodifiableMap(new LinkedHashMap<String, String>(realMap));  

This will create an unmodifiable view on a true copy of the given map, and thus nicely emulates the characteristics of the ImmutableMap without having to add the dependency to Guava.

like image 92
Marco13 Avatar answered Oct 13 '22 07:10

Marco13


Have a look at ImmutableMap JavaDoc: doc

There is information about that there:

Unlike Collections.unmodifiableMap(java.util.Map), which is a view of a separate map which can still change, an instance of ImmutableMap contains its own data and will never change. ImmutableMap is convenient for public static final maps ("constant maps") and also lets you easily make a "defensive copy" of a map provided to your class by a caller.

like image 33
Jakub H Avatar answered Oct 13 '22 08:10

Jakub H


Guava Documentation

The JDK provides Collections.unmodifiableXXX methods, but in our opinion, these can be unwieldy and verbose; unpleasant to use everywhere you want to make defensive copies unsafe: the returned collections are only truly immutable if nobody holds a reference to the original collection inefficient: the data structures still have all the overhead of mutable collections, including concurrent modification checks, extra space in hash tables, etc.

like image 37
Eric Stein Avatar answered Oct 13 '22 08:10

Eric Stein


ImmutableMap does not accept null values whereas Collections.unmodifiableMap() does. In addition it will never change after construction, while UnmodifiableMap may. From the JavaDoc:

An immutable, hash-based Map with reliable user-specified iteration order. Does not permit null keys or values.

Unlike Collections.unmodifiableMap(java.util.Map), which is a view of a separate map which can still change, an instance of ImmutableMap contains its own data and will never change. ImmutableMap is convenient for public static final maps ("constant maps") and also lets you easily make a "defensive copy" of a map provided to your class by a caller.

like image 42
Harmlezz Avatar answered Oct 13 '22 09:10

Harmlezz