Collections Framework

Views, Wrappers & Algorithms

Much of the collections framework returns views — lightweight objects backed by the original data: unmodifiable wrappers, subList ranges, map key sets, List.of and friends. Plus a toolbox of polymorphic algorithms in Collections.
  • A view shares storage with its source — changes propagate (in whichever directions are allowed)
  • Collections.unmodifiable* = read-only window; the underlying collection can still change
  • List.copyOf / Set.copyOf / Map.copyOf = true independent immutable copies
  • Algorithms: sort, binarySearch, shuffle, reverse, rotate, swap, min/max, frequency, disjoint
  • nCopies, emptyList — memory-free "virtual" collections
Which "immutable" is it?
ExpressionWhat you getUnderlying changes visible?Mutation via it
Collections.unmodifiableList(l)read-only view of lYesthrows
List.copyOf(l)independent immutable copyNothrows
List.of(...)immutable from scratchn/athrows
Arrays.asList(a)fixed-size view of arrayYes (both ways)set ok, add throws
map.keySet()view of keysYes (both ways)remove ok, add throws
list.subList(a, b)range viewYes (both ways)allowed, writes through
keySet() is not a snapshot — it edits the map
Map<String, Integer> scores = new HashMap<>(Map.of("a", 1, "b", 2, "c", 3));
scores.keySet().removeIf(k -> k.equals("b"));   // removes "b" from scores itself
// scores is now {a=1, c=3} — the returned Set IS the map's keys, not a copy

List<Integer> nums = new ArrayList<>(List.of(1, 2, 3, 4, 5));
nums.subList(1, 3).clear();                     // removes indices 1..2 from nums too
// nums is now [1, 4, 5]
The algorithms toolbox
Collections.sort(cards);                      // or cards.sort(null)
Collections.shuffle(cards);                   // Fisher–Yates
int pos = Collections.binarySearch(sorted, key);   // requires sorted input
Collections.reverse(cards);                   // in place
Collections.rotate(list, 2);                  // cycle elements
String top = Collections.max(names);          // natural order, or pass a Comparator
int dups = Collections.frequency(words, "the");
boolean none = Collections.disjoint(setA, setB); // true if no common elements
List<String> blanks = Collections.nCopies(100, ""); // O(1) memory

binarySearch returns -(insertionPoint) - 1 on a miss — the encoded slot where the key belongs, so a follow-up add(-pos - 1, key) keeps the list sorted. Passing a LinkedList defeats the purpose (random access degrades to O(n)); the method detects this via the RandomAccess marker interface.

Sources
  • Core Java, Volume I: Fundamentals (13th ed.)Ch. 9.5–9.6 — Copies and Views; Algorithms