Collections

69. List.of(), Set.of(), Map.of() and copyOf()

List.of(), Set.of(), Map.of() (Java 9+) return truly immutable, null-rejecting collections; List.copyOf() makes an immutable snapshot of an existing collection.

Java 9+ (of/copyOf); Java 21 (core language)

Explanation

The of(...) factory methods (JEP 269) return compact, truly immutable collection implementations โ€” not just unmodifiable wrappers. They: reject null elements (throw NullPointerException), throw UnsupportedOperationException on any mutation attempt (add, set, remove, clear), and have no guaranteed iteration order for Set and Map.

List.copyOf(collection) (Java 10+) returns an immutable snapshot of the given collection โ€” the result does not change if the original is modified later. It also rejects null elements.

For more than 10 entries in a Map, use Map.ofEntries(Map.entry(k1,v1), Map.entry(k2,v2), ...). Map.entry(k, v) creates an immutable Map.Entry โ€” neither k nor v may be null.

Example

import java.util.*;

public class ListOfCopyOf {
    public static void main(String[] args) {
        // List.of: truly immutable, no null
        List<String> immutable = List.of("a", "b", "c");
        System.out.println("List.of: " + immutable);

        try { immutable.add("d"); }
        catch (UnsupportedOperationException e) { System.out.println("Cannot add to List.of"); }

        try { List.of("a", null, "c"); }
        catch (NullPointerException e) { System.out.println("List.of rejects null"); }

        // Set.of: no guaranteed order, no duplicates
        Set<Integer> set = Set.of(1, 2, 3, 4, 5);
        System.out.println("Set.of contains 3: " + set.contains(3));

        try { Set.of(1, 2, 2); } // duplicate!
        catch (IllegalArgumentException e) { System.out.println("Set.of rejects duplicates"); }

        // Map.of: up to 10 entries
        Map<String, Integer> map = Map.of("one", 1, "two", 2, "three", 3);
        System.out.println("Map.of: " + map);

        // Map.ofEntries: 11+ entries
        Map<String, Integer> big = Map.ofEntries(
            Map.entry("a", 1), Map.entry("b", 2), Map.entry("c", 3),
            Map.entry("d", 4), Map.entry("e", 5), Map.entry("f", 6),
            Map.entry("g", 7), Map.entry("h", 8), Map.entry("i", 9),
            Map.entry("j", 10), Map.entry("k", 11)
        );
        System.out.println("Big map size: " + big.size());

        // List.copyOf: immutable snapshot
        List<String> mutable = new ArrayList<>(List.of("x", "y"));
        List<String> snapshot = List.copyOf(mutable);
        mutable.add("z");
        System.out.println("Snapshot: " + snapshot); // [x, y] โ€” unaffected
        System.out.println("Mutable:  " + mutable);  // [x, y, z]
    }
}

Sources