Careeroza
Chaining Comparators
thenComparing, reversed and nulls
Example
Sort by department, then by salary descending, then by name. Comparators compose like building blocks.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class Main {
record Emp(String name, String dept, int salary) { }
public static void main(String[] args) {
List<Emp> emps = new ArrayList<>(List.of(
new Emp("Ravi", "IT", 70000),
new Emp("Asha", "HR", 50000),
new Emp("Kiran", "IT", 90000),
new Emp("Meena", "IT", 70000),
new Emp("John", "HR", 65000)));
emps.sort(Comparator.comparing(Emp::dept)
.thenComparing(Emp::salary, Comparator.reverseOrder())
.thenComparing(Emp::name));
emps.forEach(e -> System.out.println(e.dept() + " " + e.salary() + " " + e.name()));
String[] names = { "Zoya", null, "amit", "Bala" };
Arrays.sort(names, Comparator.nullsLast(String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(names));
Arrays.sort(names, Comparator.nullsFirst(Comparator.<String>naturalOrder().reversed()));
System.out.println(Arrays.toString(names));
}
}Output
HR 65000 John HR 50000 Asha IT 90000 Kiran IT 70000 Meena IT 70000 Ravi [amit, Bala, Zoya, null] [null, amit, Zoya, Bala]
Cheat Sheet
| Method | Effect |
|---|---|
Comparator.comparing(keyFn) | compare by a key |
comparingInt / comparingDouble | same, avoids boxing |
.thenComparing(...) | tie-breaker |
.reversed() | reverse the whole comparator |
Comparator.reverseOrder() | reverse natural order |
Comparator.nullsFirst/nullsLast(cmp) | handle null safely |
String.CASE_INSENSITIVE_ORDER | ignore case for strings |