What are the Java 9+ List.of, Set.of, and Map.of factory methods, and why were they introduced?
answer
- Java 9 static factories on the interfaces
- One-line immutable List/Set/Map
- Mutation throws UnsupportedOperationException
- Nulls rejected with NPE
- 0–10 overloads + varargs
basics
~10 sThey are static methods added in Java 9 that build small, unchangeable collections in one line, like List.of(1, 2, 3). The returned collection cannot be added to, removed from, or modified.
solid answer
~40 sList.of, Set.of, and Map.of are static factory methods introduced in Java 9 to create compact, immutable collections concisely. Before them, building a fixed collection meant several lines (new ArrayList, repeated add calls, often wrapped in Collections.unmodifiableList). The factories collapse that to one expression: List.of("a", "b"). The returned instances are truly immutable: any mutating operation (add, remove, set, put, clear) throws UnsupportedOperationException. They also reject null elements, keys, and values, throwing NullPointerException. They have overloads for 0 to 10 elements plus a varargs version, and the implementations are memory-optimized for small sizes. They are ideal for constants, default values, and small literal data where the contents never change.
code
java · 7 linesList<String> roles = List.of("ADMIN", "USER");
Set<Integer> primes = Set.of(2, 3, 5, 7);
Map<String, Integer> ages = Map.of("Ann", 30, "Bob", 25);
// All of these throw at runtime:
// roles.add("GUEST"); -> UnsupportedOperationException
// List.of("a", null); -> NullPointerExceptiongo deeper
Knows the methods exist, can create a List/Set/Map in one line, and knows the result cannot be modified.
Explains immutability vs unmodifiable wrappers, the null rejection, and unspecified ordering of Set/Map.of.
Discusses the 0–10 overloads/memory layout, when to use factories vs builders, and thread-safety benefits of immutability.
Frames immutable collections in API-design terms: returning them from public methods to prevent caller mutation, defensive copying tradeoffs, and team conventions.
## What a collection is A *collection* in Java is an object that holds a group of other objects. `List` is an ordered sequence (allows duplicates), `Set` is a group with no duplicates, and `Map` is a set of key→value pairs. These are *interfaces* — contracts that many concrete classes (like `ArrayList`, `HashSet`, `HashMap`) implement. ## The problem before Java 9 To create a small, fixed list you had to write several statements: ```java List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); ``` If you wanted it to be *unchangeable*, you wrapped it: `Collections.unmodifiableList(list)`. That is verbose and error-prone. `Arrays.asList("a", "b")` was shorter but produced a fixed-size list that still allowed `set()` (replacing an element) and was backed by the original array. ## What the factory methods are Java 9 added *static factory methods* directly on the interfaces: - `List.of(...)` returns an immutable `List`. - `Set.of(...)` returns an immutable `Set`. - `Map.of(k1, v1, k2, v2, ...)` returns an immutable `Map`, and `Map.entry(k, v)` plus `Map.ofEntries(...)` handles larger maps. A *static factory method* is just a static method that returns an instance — you call it on the type itself (`List.of(...)`), not with `new`. ## Key properties 1. **Immutable.** Once created, the contents cannot change. Calling `add`, `remove`, `set`, `put`, or `clear` throws `UnsupportedOperationException` — an exception meaning "this operation is not allowed here." 2. **Null-hostile.** Passing `null` as an element, key, or value throws `NullPointerException`. The traditional `ArrayList`/`HashMap` allow nulls. 3. **Compact.** There are explicit overloads for 0–10 elements (so no array is allocated for small sizes) and a varargs fallback for more. 4. **Unspecified iteration order** for `Set.of` and `Map.of` — and the order can even differ between JVM runs, on purpose, so you don't accidentally depend on it. ## Why introduced The motivation was *convenience and safety*: a one-line way to build the small, never-changing collections that appear constantly in real code (configuration defaults, allowed-value sets, lookup tables) while guaranteeing nobody can mutate them by accident. Immutable data is also easier to reason about and safe to share between threads. ## Example ```java List<String> roles = List.of("ADMIN", "USER"); Set<Integer> primes = Set.of(2, 3, 5, 7); Map<String, Integer> ages = Map.of("Ann", 30, "Bob", 25); ``` Each of these is fully built, immutable, and rejects nulls.
- What happens if you call add() on a List.of result?It throws UnsupportedOperationException, because the returned list is immutable and supports no mutating operations.
- Can you put a null into Map.of?No. A null key or value throws NullPointerException immediately when the map is created.
saying these in an interview costs you the question
- Thinking List.of returns a mutable ArrayList you can add to
- Confusing it with Arrays.asList (which allows set())
- Believing nulls are allowed as elements