Java Comparator Interface¶
The Comparator interface in Java is used to define custom ordering logic for objects.
It allows you to sort objects externally, without modifying the class whose objects are being compared.
Introduced in java.util, Comparator is a cornerstone of sorting, ordering, and stream-based operations.
Why Comparator Exists¶
Java provides two ways to define sorting:
- Comparable → Natural ordering (inside the class)
- Comparator → Custom ordering (outside the class)
Comparator is used when:
- You cannot modify the class
- You want multiple sorting strategies
- Sorting logic should be decoupled from the model
Comparator vs Comparable¶
| Feature | Comparable | Comparator |
|---|---|---|
| Package | java.lang |
java.util |
| Method | compareTo() |
compare() |
| Modifies class | Yes | No |
| Multiple orderings | No | Yes |
| Lambda-friendly | Limited | Yes |
Comparator Interface Definition¶
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
````
### Return values meaning
| Return | Meaning |
|--------|--------------------|
| `< 0` | o1 comes before o2 |
| `0` | o1 equals o2 |
| `> 0` | o1 comes after o2 |
---
## Simple Example
### Sorting integers in descending order
```java
Comparator<Integer> desc = (a, b) -> b - a;
Collections.sort(list, desc);
Sorting Custom Objects¶
Example class¶
Sort by salary (ascending)¶
Comparator<Employee> bySalary =
(e1, e2) -> Double.compare(e1.salary, e2.salary);
Collections.sort(employees, bySalary);
Sort by name (alphabetical)¶
Comparator with Lambda Expressions¶
Since Comparator is a functional interface, lambdas work naturally.
Cleaner alternative:
Comparator Utility Methods (Java 8+)¶
comparing()¶
reversed()¶
thenComparing() (Multiple conditions)¶
Comparator<Employee> byDeptThenSalary =
Comparator.comparing(Employee::getDepartment)
.thenComparing(Employee::getSalary);
Null Handling¶
nullsFirst()¶
nullsLast()¶
Comparator with Streams¶
List<Employee> sorted =
employees.stream()
.sorted(Comparator.comparing(Employee::getSalary))
.toList();
Descending:
Sorting Maps Using Comparator¶
Sort Map by Key¶
Sort Map Entries by Value¶
Comparator in TreeSet / TreeMap¶
Tree-based collections rely on Comparator for ordering.
⚠️ Comparator must ensure consistent ordering, or elements may be lost.
Common Pitfalls¶
❌ Subtraction for comparison¶
✅ Use:
❌ Inconsistent comparison¶
Returning random or inconsistent values breaks TreeSet / TreeMap.
❌ Forgetting equals contract¶
Comparator should be consistent with equals where possible.
Comparator vs equals()¶
equals()checks logical equalityComparatorchecks ordering- They serve different purposes
Real-World Use Cases¶
- Sorting search results
- Ordering leaderboard data
- Multi-level sorting (date → priority → name)
- Custom UI sorting
- Stream pipelines
Interview Tips 🎯¶
- Prefer
Comparator.comparing()over manual lambdas - Mention immutability and reusability
- Avoid subtraction comparisons
- Explain difference between Comparable and Comparator clearly
Summary¶
- Comparator defines external sorting logic
- Supports multiple sorting strategies
- Functional, composable, and stream-friendly
- Essential for clean, flexible ordering logic
One-line takeaway¶
Comparator lets you decide how objects should be ordered without touching the object itself.