Part 12 — Collections Utility Class Deep Dive¶
The Collections utility class is a helper class containing static methods that operate on collections.
A common interview question is:
What is the difference between
CollectionandCollections?
This is one of the easiest questions to get wrong.
1. Collection vs Collections¶
| Collection | Collections |
|---|---|
| Interface | Utility class |
| Root interface of the Collections Framework | Contains static utility methods |
Implemented by List, Set, Queue | Cannot be instantiated |
Example:
Collection<String> c = new ArrayList<>();
vs.
Collections.sort(list);
2. Class Declaration¶
public class Collections {
// static utility methods
}
Notice:
- Final-like utility design (private constructor)
- Cannot be instantiated
- All methods are static
3. sort()¶
Example:
List<Integer> list =
Arrays.asList(5, 3, 1, 4);
Collections.sort(list);
System.out.println(list);
Output:
[1, 3, 4, 5]
Internally (modern JDK):
Collections.sort()
↓
List.sort()
↓
TimSort
4. Custom Sorting¶
Collections.sort(
employees,
Comparator.comparing(Employee::getSalary)
);
Equivalent modern syntax:
employees.sort(
Comparator.comparing(Employee::getSalary)
);
5. binarySearch()¶
Interview favorite.
Example:
List<Integer> list =
Arrays.asList(10,20,30,40,50);
int index =
Collections.binarySearch(list,30);
System.out.println(index);
Output:
2
Important¶
The collection must already be sorted.
Wrong:
40 10 20 30
Correct:
10 20 30 40
Otherwise, the result is undefined.
6. How Binary Search Works¶
Example:
10 20 30 40 50
Search:
40
Steps:
Middle = 30
↓
40 > 30
↓
Search right half
↓
Found
Complexity:
O(log n)
For ArrayList.
7. reverse()¶
Example:
Collections.reverse(list);
Before:
A B C D
After:
D C B A
Complexity:
O(n)
8. shuffle()¶
Randomizes order.
Collections.shuffle(list);
Example:
Before:
1 2 3 4 5
Possible result:
4 1 5 2 3
Common uses:
- Games
- Random sampling
- Card decks
9. swap()¶
Example:
Collections.swap(list,0,3);
Before:
A B C D
After:
D B C A
10. rotate()¶
Moves elements cyclically.
Example:
Collections.rotate(list,2);
Before:
A B C D E
After:
D E A B C
Useful for:
- Circular buffers
- Scheduling
- Round-robin algorithms
11. frequency()¶
Counts occurrences.
Collections.frequency(list,"Java");
Example:
Java
Spring
Java
Kafka
Result:
2
Complexity:
O(n)
12. min() and max()¶
Example:
Collections.min(numbers);
Collections.max(numbers);
Output:
Minimum
Maximum
Custom comparator:
Collections.max(
employees,
Comparator.comparing(Employee::getSalary)
);
13. fill()¶
Replaces every element.
Collections.fill(list,"Java");
Before:
A B C
After:
Java Java Java
14. copy()¶
Example:
Collections.copy(destination, source);
Important:
Destination must already have enough elements.
Wrong:
List<String> dest =
new ArrayList<>();
Throws:
IndexOutOfBoundsException
Correct:
List<String> dest =
new ArrayList<>(
Arrays.asList("", "", "")
);
Collections.copy(dest, source);
15. replaceAll()¶
Example:
Collections.replaceAll(
list,
"Java",
"Spring"
);
Before:
Java
Python
Java
After:
Spring
Python
Spring
16. disjoint()¶
Checks whether two collections share any elements.
Collections.disjoint(a,b);
Returns:
true
if they have no common elements.
17. singletonList()¶
Creates an immutable list with one element.
List<String> list =
Collections.singletonList("Java");
Result:
[Java]
Immutable.
18. Empty Collections¶
Useful factory methods:
Collections.emptyList()
Collections.emptySet()
Collections.emptyMap()
Advantages:
- Immutable
- Reusable singleton instances
- Avoid returning
null
Recommended API design:
return Collections.emptyList();
instead of:
return null;
19. synchronizedList()¶
Thread-safe wrapper.
List<String> list =
Collections.synchronizedList(
new ArrayList<>()
);
Internally:
Single lock
↓
Every operation synchronized
Important¶
Iteration still requires external synchronization.
Correct:
synchronized (list) {
for (String s : list) {
System.out.println(s);
}
}
Otherwise, concurrent modification may still cause problems.
20. unmodifiableList()¶
Creates a read-only view.
List<String> view =
Collections.unmodifiableList(list);
Trying:
view.add("Java");
Throws:
UnsupportedOperationException
Remember:
The original list can still change.
21. Time Complexity¶
| Method | Complexity |
|---|---|
| sort | O(n log n) |
| binarySearch | O(log n) on random-access lists |
| reverse | O(n) |
| shuffle | O(n) |
| rotate | O(n) |
| frequency | O(n) |
| min | O(n) |
| max | O(n) |
Interview note: On a LinkedList, Collections.binarySearch() is not O(log n) overall because random access is O(n). The JDK adapts its implementation, but binary search is most effective on random-access lists such as ArrayList.
Production Examples¶
Sort Employees¶
employees.sort(
Comparator.comparing(Employee::getSalary)
);
Randomize Quiz Questions¶
Collections.shuffle(questions);
API Response¶
Instead of:
return null;
Use:
return Collections.emptyList();
Safer for callers.
Read-Only Configuration¶
List<String> config =
Collections.unmodifiableList(settings);
Common Interview Questions¶
Q1. Difference between Collection and Collections?¶
| Collection | Collections |
|---|---|
| Interface | Utility class |
Q2. Which sorting algorithm does Collections.sort() use?¶
Modern JDKs delegate to List.sort(), which uses TimSort for object sorting.
Q3. Can binarySearch() work on an unsorted list?¶
No.
The list must be sorted according to the same ordering used for searching.
Q4. Difference between List.of() and Collections.unmodifiableList()?¶
| List.of() | unmodifiableList() |
|---|---|
| Truly immutable | Read-only view |
| No backing mutable collection | Backed by another collection |
Q5. Why return Collections.emptyList() instead of null?¶
It avoids unnecessary null checks and reduces the risk of NullPointerException.
Q6. Is Collections.synchronizedList() the same as CopyOnWriteArrayList?¶
No.
| synchronizedList | CopyOnWriteArrayList |
|---|---|
| Single lock | Copy-on-write |
| Better for frequent writes | Better for read-heavy workloads |
Q7. Can you modify a collection returned by Collections.singletonList()?¶
No.
It is immutable.
Q8. Does Collections.unmodifiableList() make the original list immutable?¶
No.
Only the wrapper is read-only.
Q9. Why does Collections.copy() throw IndexOutOfBoundsException?¶
Because it replaces existing elements; it does not grow the destination list.
Q10. When would you use Collections.disjoint()?¶
To efficiently check whether two collections have no common elements.
Senior Interview Scenario¶
Question:
Why is this bad API design?
public List<User> getUsers() {
return null;
}
Strong Answer:
Returning null forces every caller to perform null checks and increases the risk of NullPointerException.
A better implementation is:
return Collections.emptyList();
This clearly indicates "no results" while allowing callers to iterate safely without additional checks.
Key Takeaways¶
Collectionis an interface;Collectionsis a utility class.Collections.sort()delegates toList.sort()in modern JDKs.binarySearch()requires a sorted collection.Collections.emptyList()is preferred over returningnull.Collections.unmodifiableList()creates a read-only view, not an immutable collection.Collections.synchronizedList()provides thread safety through a single lock but still requires external synchronization during iteration.- Utility methods like
reverse(),shuffle(),rotate(),min(), andmax()are widely used in production code.
Next: Part 13 — Performance & Memory Tuning¶
We'll cover:
- Big-O analysis of all major collections
- Memory layout and object overhead
- Initial capacity tuning
- Load factor tuning
- GC impact
- Cache locality
- Choosing the right collection for production workloads
- Performance optimization strategies
- Senior-level interview questions