library
intermediateCollections.unmodifiable* vs List.of() vs List.copyOf()
Choose the right unmodifiable/immutable collection factory and understand the differences in mutability guarantees.
Java offers several ways to create read-only collections, with different guarantees:
Collections.unmodifiableList = putting a 'DO NOT TOUCH' sign on a whiteboard (someone can still erase it from behind). List.of = a printed poster (truly cannot be changed).
Key Concepts
1
1. Collections.unmodifiableList(list): returns a VIEW over the original list. Mutations through the view throw UnsupportedOperationException, but the backing list can still be modified directly (and changes are visible through the view). Not truly immutable.
2
2. List.of(elements...) (Java 9): creates a truly immutable list. No backing list. Null elements not allowed. Provides value-based equality. Iteration order matches argument order.
3
3. List.copyOf(collection) (Java 10): creates an immutable copy. If the source is already an immutable list, may return the same instance (optimization). Null elements not allowed.
4
4. Arrays.asList(array): returns a fixed-size list backed by the array. Can set() elements but can't add/remove. Changes to the array are visible in the list and vice versa.
5
Map and Set equivalents:
- Map.of(k1, v1, k2, v2), Set.of(e1, e2) — immutable
- Map.copyOf(map), Set.copyOf(set) — immutable copies
- Map.ofEntries(Map.entry(k, v), ...) — for > 10 entries
6
Null policy:
- List.of() / Map.of() / Set.of(): null not allowed (NullPointerException)
- Collections.unmodifiable*: null allowed (wraps whatever the backing collection has)