Modern Features (Java 9–25) — Java Interview Guide | Cracked Java
Mid

Modern Features (Java 9–25)

Factory methods, Stream.toList, Sequenced Collections (Java 21), Records as map keys, virtual-thread implications.

Prereqs: framework-overview

Collections evolved more in Java 9–21 than in the entire decade before. The modern era brought immutable factory methods (List.of), better stream terminators (Stream.toList), Sequenced Collections for a unified first/last API, records as first-class map keys, and — most disruptive — virtual threads, which change how you think about thread-local state and queue-based coordination.

What's new at a glance

FeatureJavaImpact
List.of, Set.of, Map.of factory methods9Replace Collections.unmodifiableX(Arrays.asList(...)) everywhere
Map.entry, Map.copyOf, List.copyOf, Set.copyOf9–10Immutable snapshots without ceremony
Stream.toList()16Concise unmodifiable list terminator
Records16Auto equals/hashCode makes them ideal map keys / set elements
Pattern matching for switch, sealed types17–21Cleaner traversal of polymorphic collection elements
Sequenced Collections (JEP 431)21Unified getFirst/getLast/reversed across List, LinkedHashSet, LinkedHashMap, Deque
Virtual threads (JEP 444)21Concurrent-collection patterns over thread-pool + bounded-queue patterns
synchronized no longer pins virtual threads (JEP 491)24Collections.synchronizedX no longer a virtual-thread hazard

Theme: immutability by default

The pre-Java-9 API had no convenient way to build a small immutable collection. You wrote Collections.unmodifiableList(new ArrayList<>(Arrays.asList("a", "b"))) and prayed nobody held a reference to the inner list. Now List.of("a", "b") does the right thing in one expression: immutable, null-hostile, structurally compact, safe to share.

The downstream effect: APIs return List.of() instead of null, callers receive immutable views by default, defensive copies become List.copyOf(in).

Theme: ordering as a first-class concept

Before Java 21, "first element of this list-or-set-or-map" was inconsistent: list.get(0), set.iterator().next(), map.entrySet().iterator().next().getKey(). Sequenced Collections unify this — any encounter-ordered collection now exposes getFirst(), getLast(), addFirst(), addLast(), removeFirst(), removeLast(), and reversed().

Theme: virtual threads change the playbook

The classic "fixed thread pool + bounded blocking queue" pattern was a workaround for OS threads being expensive. Virtual threads are cheap (millions per JVM), so you can spawn one per request and let it block on I/O directly. Consequences for collections:

  • Prefer concurrent collections (ConcurrentHashMap, ConcurrentLinkedQueue) over synchronized wrappers — millions of virtual threads contending on a monitor will still pin and serialize.
  • Prefer ScopedValue (Java 21 preview, finalizing) over ThreadLocalThreadLocal was sized for hundreds of OS threads, not millions of virtual ones.
  • The "submit to executor + take from queue" pattern is often unnecessary now — just Thread.ofVirtual().start(task).

Questions

6 in this topic