✅ Use Collections.unmodifiableXxx()
methods
Java’s Collections
class provides static factory methods to wrap a collection and prevent modifications:
List<T> readOnlyList = Collections.unmodifiableList(originalList);
Set<T> readOnlySet = Collections.unmodifiableSet(originalSet);
Map<K, V> readOnlyMap = Collections.unmodifiableMap(originalMap);
📦 Example: Read-only List
List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
List<String> readOnlyList = Collections.unmodifiableList(list);
readOnlyList.get(0); // ✅ Allowed
readOnlyList.add("orange"); // ❌ Throws UnsupportedOperationException
✅ You can read from it
❌ You can’t modify it (add, remove, clear, etc.)
⚠️ Important caveat: Shallow immutability
The unmodifiableXxx()
methods return a shallow read-only view:
- You can’t change the collection itself.
- But if it contains mutable objects, those objects can still be modified.
List<List<String>> list = new ArrayList<>();
List<String> inner = new ArrayList<>(List.of("a"));
list.add(inner);
List<List<String>> readOnly = Collections.unmodifiableList(list);
readOnly.get(0).add("b"); // ✅ Still works! Inner list is mutable.
🛡️ Bonus: Java 9+ truly immutable collections
Since Java 9, you can use the new factory methods:
List<String> list = List.of("a", "b", "c"); // Immutable list
Set<String> set = Set.of("x", "y", "z"); // Immutable set
Map<String, Integer> map = Map.of("a", 1, "b", 2); // Immutable map
These collections are:
- Unmodifiable ✅
- Fail-fast on any attempt to modify ❌
- Compact and efficient ⚡
🧠 TL;DR
Goal | Recommended Approach |
---|---|
Make existing collection read-only | Collections.unmodifiableXxx() |
Create immutable collection (Java 9+) | List.of() , Set.of() , Map.of() |
Fully immutable deep structure | You must manually ensure inner elements are immutable too |