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?
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 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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With