There are eight static methods in the Collections class that make a collection unmodifiable:
- Set<T> unmodifiableSet(Set<? extends T> set)
- List<T> unmodifiableList(List<? extends T> list)
- Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> map)
- Collection<T> unmodifiableCollection (Collection<? extends T> collection)
- SortedSet<T> unmodifiableSortedSet(SortedSet<T> sortdedSet)
- SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> sortedMap),
- NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T> navigableSet)
- NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K,? extends V> navigableMap)
Here is an example of code that creates an unmodifiable list:
List<String> list = Arrays.asList("s1", "s1");
System.out.println(list); //prints: [s1, s1]
List<String> unmodfifiableList = Collections.unmodifiableList(list);
//unmodfifiableList.set(0, "s1"); //UnsupportedOperationException
//unmodfifiableList.add("s2"); //UnsupportedOperationException
As you have probably expected, we can neither change the value of an element nor add a new element to an unmodifiable list. Nevertheless, we can change the underlying list because we still hold the reference to it. And this change will be picked up by the unmodifiable list created earlier:
System.out.println(unmodfifiableList); //prints: [s1, s1]
list.set(0, "s0");
//list.add("s2"); //UnsupportedOperationException
System.out.println(unmodfifiableList); //prints: [s0, s1]
As you can see, by changing the original list, we have managed to change the value of the element in the unmodifiable list created earlier. And that is the weakness of this way of creating unmodifiable collections, because they are basically just wrappers around regular ones.
The of() collection of factory methods do not have this weakness because they do not have two-step collection creation as in the case of unmodifiable collections. That is why there is no way to change the collection created by the of factory method. It is not possible to change either the collection composition nor any of its elements. The collections created this way are called "immutable." That is the difference between unmodifiable and immutable in the world of Java collections.