YouTip LogoYouTip

Collection Readonly

## Creating Read-Only Collections in Java In Java, there are many scenarios where you want to expose a collection to other parts of your application but prevent them from modifying its contents. Making a collection read-only (or unmodifiable) is an excellent way to enforce encapsulation, ensure thread safety for shared data, and prevent accidental bugs. This tutorial demonstrates how to use the `java.util.Collections` utility class to create read-only views of Lists, Sets, and Maps. --- ## Understanding Unmodifiable Collections The `java.util.Collections` class provides static wrapper methods that return an unmodifiable view of a specified collection. ### Key Characteristics: * **Read-Only View:** Any attempt to modify the returned collection (such as adding, removing, or updating elements) will throw an `UnsupportedOperationException`. * **Backed by the Original Collection:** The returned collection is not a separate copy; it is a wrapper around the original collection. If the original collection is modified, those changes will still be reflected in the read-only view. * **Shallow Immutability:** The collection structure itself is read-only, but if the elements inside the collection are mutable objects, their internal states can still be modified. --- ## Syntax and Methods The `Collections` class provides the following primary methods to create read-only wrappers: ```java public static List unmodifiableList(List list) public static Set unmodifiableSet(Set set) public static Map unmodifiableMap(Map m) ``` --- ## Code Example The following example demonstrates how to create read-only versions of a `List`, `Set`, and `Map`. It also shows how the collection throws an `UnsupportedOperationException` when a write operation is attempted. ### `Main.java` ```java import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; public class Main { public static void main(String[] argv) throws Exception { // 1. Create a mutable list and wrap it as read-only List stuff = Arrays.asList(new String[] { "a", "b" }); List list = new ArrayList<>(stuff); list = Collections.unmodifiableList(list); // Attempting to modify the read-only list try { list.set(0, "new value"); // This will fail } catch (UnsupportedOperationException e) { System.out.println("Notice: Modification blocked! The List is read-only."); } // 2. Create a read-only Set Set set = new HashSet<>(stuff); set = Collections.unmodifiableSet(set); // 3. Create a read-only Map Map map = new HashMap<>(); map.put("key1", "value1"); map = Collections.unmodifiableMap(map); System.out.println("Collections are now configured as read-only."); } } ``` ### Output ```text Notice: Modification blocked! The List is read-only. Collections are now configured as read-only. ``` --- ## Important Considerations ### 1. Unmodifiable vs. Immutable * **Unmodifiable:** The collection wrapper cannot be modified directly. However, if you still hold a reference to the underlying mutable collection, you can modify it, and the "read-only" wrapper will change. * **Immutable:** The collection cannot be modified under any circumstances. If you want true immutable collections, consider using Java 9+ factory methods or third-party libraries: * **Java 9+:** Use `List.of()`, `Set.of()`, or `Map.of()`. * **Guava:** Use `ImmutableList`, `ImmutableSet`, or `ImmutableMap`. ### 2. Element Mutability Making a collection read-only does not make its elements immutable. For example: ```java List users = new ArrayList<>(); users.add(new User("Alice")); List readOnlyUsers = Collections.unmodifiableList(users); // This is blocked: // readOnlyUsers.add(new User("Bob")); // This is allowed (if User has a setter): readOnlyUsers.get(0).setName("Bob"); ``` To ensure complete immutability, the objects stored inside the collection must also be immutable.
← Html ColornameCollection Array β†’