Attic
CollectionsUtilities & Concurrency

Collections Helper Class

Static algorithms for sorting, shuffling, unmodifiable and synchronized wrappers, and modern immutable factories

java.util.Collections consists exclusively of static helper methods that operate on or return collections. It cannot be instantiated.


Static Algorithms

CollectionsAlgorithms.java
List<Integer> nums = new ArrayList<>(List.of(3, 1, 4, 1, 5, 9));

// 1. Reordering & In-Place Sorting
Collections.sort(nums); // [1, 1, 3, 4, 5, 9]
Collections.sort(nums, Comparator.reverseOrder());
Collections.reverse(nums);
Collections.shuffle(nums);
Collections.swap(nums, 0, 1);

// 2. Metrics & Binary Search
int max = Collections.max(nums); // 9
int min = Collections.min(nums); // 1
int freq = Collections.frequency(nums, 1); // 2
int idx = Collections.binarySearch(nums, 4); // Must be sorted first

// 3. Disjoint Verification
boolean noOverlap = Collections.disjoint(nums, List.of(99, 100)); // true

// 4. Convenience Factories
List<String> empty = Collections.emptyList();
List<String> single = Collections.singletonList("only_one");
List<Integer> zeroes = Collections.nCopies(5, 0); // [0, 0, 0, 0, 0]

Sorting Syntax & Comparator Chaining

Java provides both static Collections.sort() and the modern instance method list.sort() (Java 8+):

SortingSyntax.java
List<Integer> list = new ArrayList<>(List.of(30, 10, 20));

// 1. Natural ascending order
Collections.sort(list); // [10, 20, 30]
list.sort(Comparator.naturalOrder());

// 2. Reverse order
Collections.sort(list, Comparator.reverseOrder()); // [30, 20, 10]
list.sort(Comparator.reverseOrder());

// 3. Object field comparator via method reference
List<Student> students = new ArrayList<>(...);
students.sort(Comparator.comparing(Student::getMarks));

// 4. Reversed object comparison
students.sort(Comparator.comparing(Student::getMarks).reversed());

// 5. Multi-level comparator chaining (sort by marks, then tiebreak by name)
students.sort(
    Comparator.comparing(Student::getMarks)
              .thenComparing(Student::getName)
);

Unmodifiable vs Synchronized Wrappers

CollectionWrappers.java
List<String> mutable = new ArrayList<>(List.of("alpha", "beta"));

// Read-only view wrapper
List<String> unmodifiable = Collections.unmodifiableList(mutable);
// unmodifiable.add("gamma"); // Throws UnsupportedOperationException!

// Thread-safe synchronized wrapper (coarse-grained lock)
List<String> synchronizedList = Collections.synchronizedList(mutable);

Collections.unmodifiableList() Is a View: It is not an independent snapshot! If code retains a reference to the underlying mutable list and modifies it, those changes are visible through the unmodifiable wrapper.


Modern Immutable Factories (Java 9+)

Java 9 introduced unmodifiable collection factories with compact internal memory representations:

ImmutableFactories.java
List<Integer> list = List.of(1, 2, 3);
Set<String> set = Set.of("A", "B", "C");
Map<Integer, String> map = Map.of(
    1, "Alice",
    2, "Bob"
);

Essential Rules:

  1. Unmodifiable: Calling add(), remove(), or put() throws UnsupportedOperationException.
  2. Null Hostile: Passing null throws NullPointerException.
  3. No Duplicates: Set.of() and Map.of() throw IllegalArgumentException on duplicate elements or keys.

On this page