Memra

Comparable<T> vs Comparator<T>

◈ 4 cards

Natural ordering with Comparable; external ordering with Comparator — the contract and the builders.

Comparable — natural, built-in ordering

java.lang.Comparable<T> expresses that a class has a natural ordering defined within itself. Implement it and override compareTo:

public class Student implements Comparable<Student> {
    String name;
    int gpa;

    Student(String name, int gpa) { this.name = name; this.gpa = gpa; }

    @Override
    public int compareTo(Student other) {
        return Integer.compare(this.gpa, other.gpa);  // ascending GPA
    }
}

List<Student> list = new ArrayList<>(...);
Collections.sort(list);  // uses compareTo — no extra argument needed

compareTo contract: return a negative integer when this < other, zero when equal, positive when this > other. The common mistake is writing this.x - other.x — this overflows for extreme int values. Use Integer.compare(a, b) instead.

Comparator — external, flexible ordering

java.util.Comparator<T> is a separate object that compares two values. It does not require the class to be modified:

// sort students by name, then by GPA descending
Comparator<Student> comp = Comparator
    .comparing(Student::name)
    .thenComparing(Comparator.comparingInt(Student::gpa).reversed());

list.sort(comp);
Comparable<T>Comparator<T>
Lives inThe class itselfA separate object
MethodcompareTo(T o)compare(T a, T b)
Used byCollections.sort, TreeSetlist.sort, TreeSet(comp)
Multiple orderings?No — one natural orderYes — compose as many as needed
returned 0comparing(Student::name)compare the names firstthenComparing(gpa reversed)only reached on a tie
thenComparing is a tie-breaker, not a second sort: it is asked only when the comparator before it returned 0. Swap the order of the calls and you get a different ordering.
NORMAL ~/memra/learn/java-from-zero/comparable-and-comparator utf-8 LF