Unmodifiable vs Immutable Collections

Naveen AnamaneniUpdated · 4 min read

Java has two kinds of "read-only" collections, and they are often confused. An unmodifiable view, created with Collections.unmodifiableList(list), blocks changes made through the view, but it still reflects changes made to the original list behind it. An immutable collection, created with List.of or List.copyOf, has no original behind it, so its contents never change. In this lesson, you will see the difference in code and learn when to use each.

Example: A View vs a Copy

Let's see an example where the original list changes after both are created.

ViewVsCopy.java▶ Try it
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
public class ViewVsCopy {
    public static void main(String[] args) {
        List<String> original = new ArrayList<>(List.of("Navika", "Srihitha"));
 
        List<String> view = Collections.unmodifiableList(original);
        List<String> copy = List.copyOf(original);
 
        original.add("Advitha");
 
        System.out.println("original: " + original);
        System.out.println("view:     " + view);
        System.out.println("copy:     " + copy);
 
        try {
            view.add("Anamaneni");
        } catch (UnsupportedOperationException e) {
            System.out.println("view.add rejected");
        }
    }
}
Output
original: [Navika, Srihitha, Advitha]
view:     [Navika, Srihitha, Advitha]
copy:     [Navika, Srihitha]
view.add rejected

Explanation: Both the view and the copy reject add. But when the original list gained Advitha, the view showed it too, because the view is just a read-only window onto the original. The copy didn't change, because it holds its own elements.

A view is a read-only window onto live data; a copy has its own fixed data

Differences

Unmodifiable viewImmutable collection
Created withCollections.unmodifiableList/Set/Map(...)List.of, Set.of, Map.of, copyOf, stream.toList()
Changes through itRejectedRejected
Changes to the originalVisibleNot applicable: there's no original
Copies the elementsNo, it wrapsYes
null elementsAllowed if the original has themNot allowed
Cost to createVery cheap (a small wrapper)Copies the elements

When to Use Each

  • Use an unmodifiable view when a class wants to let callers see live data that the class itself keeps updating, without letting them change it. For example, a playlist object can return a read-only view of its songs.
  • Use an immutable copy when you want a snapshot that will never change, for example storing a list passed into a constructor, or sharing data between threads.

Common Mistakes

Assuming Collections.unmodifiableList makes the data safe from all changes. Anyone holding the original list can still change it.

Wrapping a list twice to "make it more immutable". It's still a view of the same original.

Calling List.copyOf on an already-immutable list and expecting a new copy. It may return the same object, which is fine because it can't change.

Interview Corner

What is the difference between an unmodifiable and an immutable collection?

An unmodifiable collection, such as the one returned by Collections.unmodifiableList, is a read-only wrapper around another collection: modification methods throw UnsupportedOperationException, but changes made to the underlying collection are visible through the wrapper. An immutable collection, such as one from List.of or List.copyOf, holds its own elements and can never change by any route. Unmodifiable views are cheap and live; immutable collections are snapshots that are safe to share.

Practice

  1. Easy: Repeat the example with a Map: create an unmodifiable view and a Map.copyOf, then put a new key in the original and print all three.
  2. Harder: Write a Course class that keeps an internal ArrayList of students, offers addStudent, and exposes students() as an unmodifiable view. Show that a caller sees new students but can't add any.

Quick check: Unmodifiable vs immutable

4 questions
1Does an unmodifiable view show changes made to the original list?
2Which creates an immutable snapshot?
3What happens when you call add on either kind?
4Are the elements inside an immutable list automatically immutable?

Key Takeaways

Was this tutorial helpful?

Lesson 297 of 482