Java Collections Utility Class
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+) orList.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
Collections(plural) is a utility class — don’t confuse withCollection(interface).- Use
Collections.sort()orlist.sort()for sorting. - Unmodifiable wrappers are views — use
List.of()/List.copyOf()for true immutability. - Synchronized wrappers provide basic thread safety; prefer concurrent collections for performance.
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.