The java.util.Collections Utility Class
While the Java Collections Framework provides various data structure interfaces and implementations, the java.util.Collections class acts as a powerful companion. It consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "wrappers", which return a new collection backed by a specified collection, and a few other odds and ends.
Sorting and Searching
One of the most common uses of the Collections class is sorting and searching lists.
Sorting
You can sort a List into ascending order using its natural ordering or a custom Comparator:
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9));
Collections.sort(numbers);
// Output: [1, 2, 5, 8, 9]
List<String> words = new ArrayList<>(Arrays.asList("apple", "Banana", "cherry"));
Collections.sort(words, String.CASE_INSENSITIVE_ORDER);
Binary Search
For searching an element in a sorted list efficiently ():
int index = Collections.binarySearch(numbers, 5);
// Returns the index of '5'
Note: The list must be sorted prior to calling binarySearch.
Modifying Elements
The Collections class offers methods to manipulate the elements within a list:
reverse(List<?> list): Reverses the order of the elements.shuffle(List<?> list): Randomly permutes the elements using a default source of randomness.swap(List<?> list, int i, int j): Swaps the elements at the specified positions.fill(List<? super T> list, T obj): Replaces all elements with the specified element.
Collections.shuffle(numbers); // Randomizes the list
Collections.reverse(numbers); // Reverses it
Synchronization Wrappers
Standard collections like ArrayList and HashMap are not thread-safe. If multiple threads access a collection concurrently, and at least one modifies it, it must be synchronized externally. The Collections class provides wrappers to make collections thread-safe:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
Important: When iterating over a synchronized collection using an Iterator or enhanced for-loop, you must manually synchronize on the returned collection:
synchronized (syncList) {
for (String item : syncList) {
System.out.println(item);
}
}
Unmodifiable Wrappers
Unmodifiable wrappers provide a read-only view of a collection. Any attempt to modify the returned collection results in an UnsupportedOperationException.
List<String> readOnlyList = Collections.unmodifiableList(new ArrayList<>(Arrays.asList("A", "B", "C")));
// readOnlyList.add("D"); // Throws UnsupportedOperationException
This is extremely useful for exposing internal data structures to external clients without giving them modification rights.
Singleton and Empty Collections
The utility class also provides ways to create memory-efficient single-element or empty collections:
Collections.emptyList(),Collections.emptySet(),Collections.emptyMap(): Returns an immutable empty collection. Useful to avoid returningnullfrom methods.Collections.singletonList(T o),Collections.singleton(T o),Collections.singletonMap(K key, V value): Returns an immutable collection containing only the specified object.
public List<String> getNames() {
if (names == null) {
return Collections.emptyList(); // Better than returning null
}
return names;
}
The java.util.Collections class is an indispensable tool in the Java developer's arsenal, greatly simplifying common collection operations and ensuring robust concurrent designs.