Java Collections Utility Class

3 minute read

java.util.Collections is a utility class (all static methods) that provides algorithms and wrappers for working with collections. Don’t confuse it with the Collection interface.

Collection (interface) Collections (class)
Root interface for List, Set, Queue Utility class with static helper methods
java.util.Collection java.util.Collections

Sorting

List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));

Collections.sort(names);
// [Alice, Bob, Charlie] — natural order

Collections.sort(names, Comparator.reverseOrder());
// [Charlie, Bob, Alice]

// Or use List.sort() directly (Java 8+):
names.sort(Comparator.comparing(String::length));
// [Bob, Alice, Charlie]

Searching

List<Integer> numbers = List.of(10, 20, 30, 40, 50);  // must be sorted

int index = Collections.binarySearch(numbers, 30);  // 2
int missing = Collections.binarySearch(numbers, 25); // negative (insertion point)

The list must be sorted before calling binarySearch(). Otherwise results are undefined.


Reordering

List<String> list = new ArrayList<>(List.of("A", "B", "C", "D", "E"));

Collections.reverse(list);     // [E, D, C, B, A]
Collections.shuffle(list);     // random order
Collections.rotate(list, 2);   // shift right by 2: [D, E, A, B, C]
Collections.swap(list, 0, 4);  // swap indices 0 and 4

Min and Max

List<Integer> nums = List.of(42, 7, 99, 23);

Collections.min(nums);  // 7
Collections.max(nums);  // 99

// With comparator
Collections.min(names, Comparator.comparing(String::length));

Frequency and Disjoint

List<String> words = List.of("hello", "world", "hello", "java", "hello");

Collections.frequency(words, "hello");  // 3

List<String> a = List.of("A", "B", "C");
List<String> b = List.of("D", "E", "F");
Collections.disjoint(a, b);  // true — no elements in common

Unmodifiable Wrappers

Wrap a mutable collection to prevent modification:

List<String> mutable = new ArrayList<>(List.of("A", "B", "C"));
List<String> unmodifiable = Collections.unmodifiableList(mutable);

unmodifiable.add("D");  // ❌ UnsupportedOperationException
mutable.add("D");       // ✅ Changes are visible through unmodifiable view!

Caveat: The wrapper is a view — modifications to the underlying collection are visible. For true immutability, use List.copyOf() (Java 10+) or List.of().

Method Truly Immutable? Null Elements
Collections.unmodifiableList(list) ❌ (view) ✅
List.of(...) ✅ ❌
List.copyOf(list) ✅ (copy) ❌

Synchronized Wrappers

Make collections thread-safe (with coarse-grained locking):

List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());

Caution: Iteration still requires manual synchronization:

synchronized (syncList) {
    for (String item : syncList) {
        System.out.println(item);
    }
}

For better concurrent performance, prefer ConcurrentHashMap, CopyOnWriteArrayList, etc.


Singleton and Empty Collections

// Single-element immutable collections
List<String> single = Collections.singletonList("only");
Set<String> singleSet = Collections.singleton("only");
Map<String, Integer> singleMap = Collections.singletonMap("key", 42);

// Empty immutable collections
List<String> empty = Collections.emptyList();
Set<String> emptySet = Collections.emptySet();
Map<String, Integer> emptyMap = Collections.emptyMap();

Modern alternative (Java 9+): List.of("only"), List.of(), Map.of().


Fill and Replace

List<String> list = new ArrayList<>(List.of("A", "B", "C", "D"));

Collections.fill(list, "X");  // [X, X, X, X]

list = new ArrayList<>(List.of("A", "B", "A", "C"));
Collections.replaceAll(list, "A", "Z");  // [Z, B, Z, C]

nCopies()

Create an immutable list of n identical elements:

List<String> fiveStars = Collections.nCopies(5, "★");
// [★, ★, ★, ★, ★]

Checked Collections (Type Safety at Runtime)

Catch type violations that bypass generics (e.g., via raw types):

List<String> list = new ArrayList<>();
List<String> checked = Collections.checkedList(list, String.class);

// Through raw type bypass:
List raw = checked;
raw.add(42);  // ❌ ClassCastException at runtime — caught immediately!

Quick Reference

Method Description
sort(list) Sort in natural order
sort(list, comparator) Sort with custom comparator
binarySearch(list, key) Binary search (list must be sorted)
reverse(list) Reverse element order
shuffle(list) Random shuffle
swap(list, i, j) Swap two elements
rotate(list, distance) Rotate elements
min(collection) / max(collection) Find min/max
frequency(collection, obj) Count occurrences
disjoint(c1, c2) Check no common elements
unmodifiableList(list) Read-only view
synchronizedList(list) Thread-safe wrapper
singletonList(obj) Immutable single-element list
emptyList() Immutable empty list
nCopies(n, obj) Immutable list of n copies
fill(list, obj) Fill all positions
replaceAll(list, old, new) Replace all occurrences

Key Takeaways

  1. Collections (plural) is a utility class — don’t confuse with Collection (interface).
  2. Use Collections.sort() or list.sort() for sorting.
  3. Unmodifiable wrappers are views — use List.of()/List.copyOf() for true immutability.
  4. Synchronized wrappers provide basic thread safety; prefer concurrent collections for performance.
  5. emptyList(), singletonList(), nCopies() are useful for edge cases and defaults.

What’s Next?

Next: Comparable and Comparator — natural ordering, custom ordering, and lambda-based sorting.

Updated: