Skip to content

Lesson 03 · Core Collections

Objectives

After this lesson you will be able to:

  • Choose between List, Set, Map, Queue/Deque and their main implementations.
  • Use factory methods (List.of, Map.of) and know their immutability.
  • Iterate and remove safely.

The framework at a glance

InterfaceMeaningCommon impls
Listordered, indexed, duplicates OKArrayList, LinkedList
Setno duplicatesHashSet, LinkedHashSet, TreeSet
Mapkey → value (not a Collection)HashMap, LinkedHashMap, TreeMap
Queue/DequeFIFO / double-endedArrayDeque, LinkedList

HashSet/HashMap are unordered; the Linked* variants keep insertion order; the Tree* variants keep sorted order (and require Comparable elements/keys or a Comparator).

java
List<String> list = new ArrayList<>();
Set<Integer> set  = new HashSet<>();
Map<String,Integer> map = new HashMap<>();
Deque<Integer> stack = new ArrayDeque<>();   // push/pop/peek

Factory methods (immutable)

List.of, Set.of, Map.of build compact unmodifiable collections.

java
List<Integer> xs = List.of(1, 2, 3);
xs.add(4);            // UnsupportedOperationException — immutable
Map<String,Integer> m = Map.of("a", 1, "b", 2);

Exam trap

List.of(...) etc. are immutable: any mutator throws UnsupportedOperationException. They also reject null elements/keys (NPE), unlike ArrayList/HashMap. Set.of/Map.of throw IllegalArgumentException on duplicate elements/keys.

Useful Map methods

java
map.getOrDefault("x", 0);
map.putIfAbsent("a", 1);
map.computeIfAbsent("k", key -> new ArrayList<>()).add(v);   // multimap idiom
map.merge("a", 1, Integer::sum);                              // counter idiom

Iterating and removing safely

Removing during a for-each throws ConcurrentModificationException (Module 02). Use an Iterator or removeIf:

java
list.removeIf(s -> s.isBlank());
for (var it = list.iterator(); it.hasNext(); ) {
    if (cond(it.next())) it.remove();
}

SDET note

For deterministic tests, prefer ordered implementations (LinkedHashMap/LinkedHashSet) or sort before asserting — HashMap/HashSet iteration order is unspecified and can differ across JVMs, making assertEquals on a toString() flaky.

Key Takeaways

  • List (indexed, dup OK), Set (no dups), Map (key→value, not a Collection), Queue/Deque (FIFO/double-ended). Linked* keep insertion order; Tree* keep sorted order.
  • List.of/Set.of/Map.of are immutable, reject null, and (Set/Map) reject duplicates — mutating throws UnsupportedOperationException.
  • Use getOrDefault/computeIfAbsent/merge for common Map patterns.
  • Remove during iteration with Iterator.remove() or removeIf, never inside a for-each.

Lesson Quiz

Lesson Quiz · Core Collections0 / 5
  1. What does List.of(1,2).add(3) do?

    • AReturns [1,2,3]
    • BUnsupportedOperationException
    • CCompile error
    • DIllegalArgumentException
  2. Which Set keeps elements in SORTED order?

    • AHashSet
    • BLinkedHashSet
    • CTreeSet
    • DArraySet
  3. What does Map.of("a",1).put("b",2) throw?

    • ANothing
    • BUnsupportedOperationException
    • CNullPointerException
    • DClassCastException
  4. Which idiom safely accumulates into a multimap?

    • Amap.get(k).add(v)
    • Bmap.computeIfAbsent(k, x -> new ArrayList<>()).add(v)
    • Cmap.put(k, v)
    • Dmap.merge(k, v)
  5. Is List.of(1, null, 2) legal?

    • AYes
    • BNo — List.of rejects null (NPE)
    • COnly with HashSet
    • DOnly in Java 21

Next: Sequenced Collections. Run the matching code in labs/src/main/java/com/jse21/m05_collections/.