Memra

Comparable<T> vs Comparator<T>

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 in | The class itself | A separate object | | Method | compareTo(T o) | compare(T a, T b) | | Used by | Collections.sort, TreeSet | list.sort, TreeSet(comp) | | Multiple orderings? | No — one natural order | Yes — compose as many as needed |

NORMAL ~/memra/learn/java-from-zero/comparable-and-comparator utf-8 LF