Collections.unmodifiableCollection

`Collections.unmodifiableCollection` creates a read-only view over an existing collection; it does not create an independent immutable copy. Changes made through another reference to the backing collection remain visible through the view.

The `Collections.unmodifiableCollection` method accepts an existing `Collection` and returns a wrapper that permits read operations but rejects mutation attempts through the wrapper with `UnsupportedOperationException`. The wrapped collection remains the actual storage for the data.

Because the result is a view, changes to the original collection can still change what the unmodifiable view exposes. Therefore, wrapping a collection does not make the underlying data immutable or prevent other code holding the original reference from modifying it.

The wrapper also affects operations exposed through the `Collection` interface, including mutating methods such as `add`, `remove`, and `clear`. Iterators obtained from the unmodifiable view do not provide mutation through `Iterator.remove()` either.

Use an unmodifiable view when you want to expose collection data without allowing callers to mutate it through that reference. If the underlying collection must also be isolated from later changes, first create a defensive copy and then expose that copy through an unmodifiable wrapper.

Key points

Interview questions

What does `Collections.unmodifiableCollection` do?

It returns a read-only wrapper around an existing collection. Attempts to modify the wrapper generally result in `UnsupportedOperationException`. The original collection remains mutable if another reference to it exists. The wrapper therefore protects the access path, not the underlying object itself.

Does `Collections.unmodifiableCollection` make the original collection immutable?

No. The original collection can still be modified through another reference. Those changes can then be observed through the unmodifiable view. The wrapper only prevents mutations performed through the wrapped reference.

What happens when you call `add` on an unmodifiable collection?

The operation is rejected by the wrapper and an `UnsupportedOperationException` is thrown. This applies even when the backing collection itself supports `add`. Code that owns the original collection can still modify it through the original reference.

How would you expose a collection without allowing callers to observe later changes to the original?

Create a defensive copy first, then expose that copy through an unmodifiable wrapper. For example, copy the source into a new collection and pass that new collection to `Collections.unmodifiableCollection`. This separates the exposed data from later mutations of the caller's original collection.

What is the key distinction between an unmodifiable view and an immutable collection?

An unmodifiable view is an access restriction layered over mutable storage. If the backing collection changes elsewhere, the view can reflect those changes. An immutable collection instead represents state that cannot be changed through any supported mutation path, although the exact guarantees depend on the implementation and whether contained objects are themselves mutable.