skip to content

What are the Collections.emptyList and singletonList factories, and why are they useful?

level: juniorimportance: should knowfreq 45%

answer

  1. emptyList/Set/Map = shared immutable zero-element
  2. singletonList/singleton/singletonMap = immutable one element
  3. return empty over null to skip null checks
  4. all immutable -> mutators throw
  5. List.of is the Java 9+ uniform alternative (rejects null)

basics

~10 s

Collections.emptyList() gives you a shared, immutable empty list, and singletonList(x) gives an immutable one-element list. They are handy lightweight return values when you'd otherwise create a tiny list, and they can't be modified.

solid answer

~40 s

Collections.emptyList(), emptySet(), and emptyMap() return shared, immutable, zero-element collections — the empty list is a cached singleton, so calling it repeatedly allocates nothing. Collections.singletonList(x), singleton(x) (a set), and singletonMap(k,v) return immutable collections holding exactly one element, implemented with a compact internal layout. They are useful as cheap return values: returning emptyList() instead of null avoids null checks, and singletonList is a tidy way to pass one item to an API that wants a collection. All of them throw UnsupportedOperationException on mutation. In Java 9+ List.of() and List.of(x) cover the same ground with a more uniform API, so new code often prefers those, but the Collections factories remain widely used and valid.

code

java · 10 lines
java
// No results: return an empty list, not null
List<String> results = found ? hits : Collections.emptyList();

// One item into a List-shaped API
process(Collections.singletonList("only"));

Collections.singletonList("x").add("y"); // throws UnsupportedOperationException

// Java 9+ uniform alternative
List<String> alt = List.of("only");

go deeper

for a junior

Knows emptyList()/singletonList(x) give small immutable collections and that returning empty beats returning null.

for a middle

Knows the empty instances are shared/cached (zero allocation) and that all are immutable; distinguishes the two senses of 'singleton'.

for a senior

Compares with List.of/Map.of (null handling, uniformity) and uses empty returns as an API-design convention.

for a principal

Sets codebase conventions (never return null collections), reasons about allocation/garbage and immutable-value sharing across APIs.

## The factories `Collections` provides tiny pre-built collections: - **Empty:** `emptyList()`, `emptySet()`, `emptyMap()` — collections with **zero** elements. - **Singleton:** `singletonList(x)` (one-element list), `singleton(x)` (one-element *set*), `singletonMap(k, v)` (one-entry map). All of them are **immutable** — any mutating call (`add`, `remove`, `clear`, `put`) throws `UnsupportedOperationException`. ## Why they exist: cheap, intention-revealing values 1. **Avoid returning `null`.** A method that sometimes has no results should return an *empty* collection, not `null`, so callers can loop without a null check. `return Collections.emptyList();` does this with **zero allocation** — the empty list is a single cached, shared instance (a singleton), reused every time. Allocating `new ArrayList<>()` each time would create garbage for no reason. 2. **Pass one item to a collection-shaped API.** When a method wants a `List<T>` but you have exactly one element, `Collections.singletonList(x)` is a compact one-liner instead of building an `ArrayList` and adding to it. Because they are immutable and (for empty) shared, they are both memory-efficient and safe to return without defensive copying — nobody can mutate them. ## Type inference note on emptyList `emptyList()` is generic, so sometimes you must help the compiler infer the element type, e.g. `Collections.<String>emptyList()` or by assigning to a typed variable `List<String> xs = Collections.emptyList();`. ## Relationship to List.of (Java 9+) `List.of()` (empty) and `List.of(x)` (single element) and `Map.of(k,v)` cover the same needs with one uniform, overloaded factory family. Differences worth knowing: - `singletonList` permits a `null` element; `List.of` rejects `null` (throws `NullPointerException`). - The `Collections` empty factories return a cached shared instance; `List.of()` likewise returns an effectively shared empty instance. New code often standardizes on `List.of` / `Map.of` for consistency, but the `Collections` factories are perfectly valid and ubiquitous in existing code and APIs. ## Key terms - **Factory method:** a static method that produces an object, hiding the construction details. - **Singleton (object sense):** a single shared instance reused everywhere — here, the cached empty collection. - **Singleton (collection sense):** a collection containing exactly one element (the meaning in `singletonList`). - **Immutable:** cannot be changed after creation; mutators throw `UnsupportedOperationException`.

  • Why return Collections.emptyList() instead of null?
    Callers can iterate or stream over it without a null check, eliminating a whole class of NullPointerExceptions; and it allocates nothing because the empty list is a shared cached instance.
  • What is the Java 9+ equivalent of singletonList(x)?
    List.of(x). It is immutable too, but it rejects null elements, whereas singletonList allows a single null.

saying these in an interview costs you the question

  • Returning null instead of emptyList for 'no results'
  • Trying to add to a singletonList
  • Confusing 'singleton' the design pattern with singletonList the one-element collection
  • Assuming singletonList rejects null (it allows null; List.of does not)

context