Comparable, Comparator, sorting
Define one natural order and build any number of alternative orders on demand.
Open this lesson in the learning hubKey points
Comparablelives on the class: one natural order.Comparatoris a separate object, so you can have many.- Build comparators declaratively:
Comparator.comparing(Employee::dept).thenComparing(Employee::name). - Flip direction with
reversed(), or passComparator.reverseOrder()to a single key. - For
int,long,doublekeys usecomparingIntand friends — they avoid boxing. - Use
Integer.compare(a, b), nevera - b. Subtraction overflows and silently reverses your order. List.sortis stable: equal elements keep their order.TreeSettreats compare-to-zero as a duplicate.
Example
import java.util.*;
public class Main {
record Employee(String name, String dept, int salary) implements Comparable<Employee> {
@Override public int compareTo(Employee other) {
return Integer.compare(salary, other.salary);
}
@Override public String toString() { return name + "(" + dept + "," + salary + ")"; }
}
public static void main(String[] args) {
List<Employee> staff = new ArrayList<>(List.of(
new Employee("Ana", "eng", 120),
new Employee("Bo", "ops", 90),
new Employee("Cy", "eng", 90),
new Employee("Di", "ops", 120)));
Collections.sort(staff);
System.out.println("natural (salary) : " + staff);
staff.sort(Comparator.comparing(Employee::name));
System.out.println("by name : " + staff);
staff.sort(Comparator.comparing(Employee::dept)
.thenComparing(Employee::salary, Comparator.reverseOrder())
.thenComparing(Employee::name));
System.out.println("dept, salary desc : " + staff);
System.out.println("max by salary : " + Collections.max(staff));
System.out.println("min by name : " + Collections.min(staff, Comparator.comparing(Employee::name)));
List<String> withNulls = new ArrayList<>(Arrays.asList("b", null, "a"));
withNulls.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
System.out.println("nullsFirst : " + withNulls);
TreeSet<Employee> bySalary = new TreeSet<>(Comparator.comparingInt(Employee::salary));
bySalary.addAll(staff);
System.out.println("TreeSet by salary : " + bySalary + " (90 and 120 'equal' -> deduped!)");
}
}
One natural order via Comparable, every other order via Comparator.comparing chains.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Collections course, and every lesson in it is listed on the Collections contents page.