Contents

Collections.sort() performs a stable O(n log n) sort in-place. reverse() reverses the current order without sorting. binarySearch() requires a pre-sorted list and returns the index of the target, or a negative value indicating where it would be inserted:

import java.util.*; List<Integer> nums = new ArrayList<>(List.of(3, 1, 4, 1, 5, 9, 2, 6)); // sort — stable, O(n log n) Collections.sort(nums); System.out.println(nums); // [1, 1, 2, 3, 4, 5, 6, 9] // sort with Comparator Collections.sort(nums, Comparator.reverseOrder()); System.out.println(nums); // [9, 6, 5, 4, 3, 2, 1, 1] // reverse — reverses current order (not the same as sort descending) Collections.reverse(nums); System.out.println(nums); // [1, 1, 2, 3, 4, 5, 6, 9] — reversed back // binarySearch — list MUST be sorted ascending; returns index or (-(insertion point) - 1) Collections.sort(nums); int idx = Collections.binarySearch(nums, 5); System.out.println(idx); // e.g. 5 (index of value 5) int missing = Collections.binarySearch(nums, 7); System.out.println(missing); // negative (not found) // binarySearch with Comparator — list must be sorted with same Comparator List<String> words = new ArrayList<>(List.of("Apple", "banana", "Cherry")); Collections.sort(words, String.CASE_INSENSITIVE_ORDER); int pos = Collections.binarySearch(words, "cherry", String.CASE_INSENSITIVE_ORDER); System.out.println(pos); // found index // rotate — rotates elements by distance positions List<Integer> r = new ArrayList<>(List.of(1, 2, 3, 4, 5)); Collections.rotate(r, 2); // right-rotate by 2 System.out.println(r); // [4, 5, 1, 2, 3]

shuffle() randomises a list in-place using a Random source. fill() replaces every element with a single value. nCopies() creates an immutable list of repeated elements — handy for initialising a mutable list via the copy constructor. copy() bulk-copies elements into an existing list:

List<Integer> deck = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); // shuffle — randomizes in-place using default Random (or supplied Random for reproducibility) Collections.shuffle(deck); System.out.println(deck); // random order Collections.shuffle(deck, new Random(42)); // seeded — reproducible shuffle // fill — replace all elements with a single value List<String> grid = new ArrayList<>(Collections.nCopies(9, "")); // 9 empty strings Collections.fill(grid, "X"); System.out.println(grid); // [X, X, X, X, X, X, X, X, X] // nCopies — immutable list with n copies of an object List<Integer> zeros = Collections.nCopies(5, 0); System.out.println(zeros); // [0, 0, 0, 0, 0] // Useful for pre-populating or initializing arrays // copy — copies src elements into dest (dest must be at least as large as src) List<Integer> src = List.of(10, 20, 30); List<Integer> dest = new ArrayList<>(Collections.nCopies(5, 0)); Collections.copy(dest, src); // dest[0..2] = src[0..2] System.out.println(dest); // [10, 20, 30, 0, 0] // swap — swap two elements by index List<String> letters = new ArrayList<>(List.of("a", "b", "c", "d")); Collections.swap(letters, 0, 3); System.out.println(letters); // [d, b, c, a] // replaceAll — replace all occurrences of oldVal with newVal List<String> data = new ArrayList<>(List.of("a", "b", "a", "c", "a")); Collections.replaceAll(data, "a", "X"); // not the same as List.replaceAll(UnaryOperator) System.out.println(data); // [X, b, X, c, X]

Collections.min() and max() scan a collection for its extreme values using natural order or a Comparator. frequency() counts occurrences of an element. disjoint() returns true if two collections share no elements:

List<Integer> values = List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 5); // min and max — uses natural order (or Comparator) System.out.println(Collections.min(values)); // 1 System.out.println(Collections.max(values)); // 9 // With Comparator List<String> words = List.of("fig", "apple", "banana"); System.out.println(Collections.min(words, Comparator.comparingInt(String::length))); // "fig" System.out.println(Collections.max(words, Comparator.comparingInt(String::length))); // "banana" // frequency — count occurrences of an element System.out.println(Collections.frequency(values, 5)); // 3 System.out.println(Collections.frequency(values, 7)); // 0 // disjoint — true if no element in common List<Integer> a = List.of(1, 2, 3); List<Integer> b = List.of(4, 5, 6); List<Integer> c = List.of(3, 4, 5); System.out.println(Collections.disjoint(a, b)); // true — no common elements System.out.println(Collections.disjoint(a, c)); // false — 3 is in both // Works with any two Collection types Set<String> set = Set.of("x", "y"); List<String> list = List.of("a", "b", "x"); System.out.println(Collections.disjoint(set, list)); // false — "x" in common // Practical: count word frequencies in a list List<String> tokens = List.of("the", "cat", "sat", "on", "the", "mat", "the"); Set<String> unique = new HashSet<>(tokens); unique.forEach(w -> System.out.println(w + ": " + Collections.frequency(tokens, w))); // For large datasets, use a HashMap counter instead — O(n) vs O(n * unique)

Collections.unmodifiableList() and its siblings create read-only views — mutation methods throw UnsupportedOperationException. Crucially, the view is backed by the original collection, so changes to the original are still visible. For a true immutable snapshot, use List.copyOf() (Java 10+):

// Collections.unmodifiable* — read-only view of a collection // Mutations throw UnsupportedOperationException List<String> mutable = new ArrayList<>(List.of("a", "b", "c")); List<String> readOnly = Collections.unmodifiableList(mutable); System.out.println(readOnly.get(0)); // "a" — reads work // readOnly.add("d"); // UnsupportedOperationException // IMPORTANT: the view is backed by the original — changes to mutable show in readOnly mutable.add("d"); System.out.println(readOnly.size()); // 4 — sees the change! // For a true immutable snapshot, use List.copyOf() (Java 10+) or List.of() List<String> snapshot = List.copyOf(mutable); // independent copy, immutable // Other unmodifiable wrappers Set<String> uSet = Collections.unmodifiableSet(new HashSet<>()); Map<String, Integer> uMap = Collections.unmodifiableMap(new HashMap<>()); SortedSet<String> uSSet = Collections.unmodifiableSortedSet(new TreeSet<>()); SortedMap<String,?> uSMap = Collections.unmodifiableSortedMap(new TreeMap<>()); // Singleton collections — single-element immutable collections List<String> one = Collections.singletonList("only"); Set<String> ons = Collections.singleton("only"); Map<String, Integer> onm = Collections.singletonMap("key", 42); // emptyList/emptySet/emptyMap — canonical immutable empty collections List<String> empty = Collections.emptyList(); // type-safe, no allocation // Prefer List.of(), Set.of(), Map.of() for modern code (Java 9+) Prefer List.of(), Set.of(), and Map.of() (Java 9+) over Collections.unmodifiableList() for new code. They are truly immutable (not backed by a mutable source), more concise, and often more memory-efficient.

Collections.synchronizedList() and related wrappers synchronise every individual method call, but compound operations (check-then-act, iteration) still require explicit synchronized blocks on the wrapper object. For new concurrent code prefer the java.util.concurrent collections:

// Collections.synchronized* — wrap any collection for thread-safety // Every method is synchronized on the wrapper object List<String> syncList = Collections.synchronizedList(new ArrayList<>()); syncList.add("item1"); // thread-safe add syncList.add("item2"); // CRITICAL: iteration must be manually synchronized! synchronized (syncList) { for (String s : syncList) { // safe — holds the lock System.out.println(s); } } // Without the synchronized block, another thread could modify syncList during iteration // Other synchronized wrappers Set<String> syncSet = Collections.synchronizedSet(new HashSet<>()); Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>()); // Modern alternative — prefer java.util.concurrent classes for new code // CopyOnWriteArrayList — thread-safe, iteration doesn't need external sync // (good for read-heavy, infrequent-write scenarios) import java.util.concurrent.*; List<String> cowList = new CopyOnWriteArrayList<>(); cowList.add("a"); cowList.add("b"); for (String s : cowList) { // safe — iterates over a snapshot System.out.println(s); } // ConcurrentHashMap — better than synchronizedMap for concurrent access Map<String, Integer> concMap = new ConcurrentHashMap<>(); concMap.put("a", 1); concMap.computeIfAbsent("b", k -> 2); // atomic operation The synchronized wrappers from Collections require external synchronization for compound operations (check-then-act, iteration). For production concurrent code, use the dedicated classes from java.util.concurrentConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue implementations — which are designed for concurrent use without external locking.