Короткий ответ
Comparable задаёт «естественный» порядок самого класса: класс реализует интерфейс и метод compareTo(Object o), в котором зашито правило «я больше или меньше другого». Так устроены стандартные классы — String, Integer, Date. Comparator — отдельный класс или лямбда с методом compare(a, b), который не требует изменять сравниваемый класс, поэтому для одного типа можно завести много стратегий сортировки.
Как это работает подробнее
Отсортировать коллекцию можно через Collections.sort(...) или list.sort(...): если передан только список, элементы должны реализовывать Comparable; если нужен особый порядок — вторым аргументом передаётся Comparator. У Comparator есть удобные дефолтные методы comparing(...), thenComparing(...), reversed(), из которых собирается составная сортировка.
- Comparable: один естественный порядок в самом классе — например, по id.
- Comparator: порядок зависит от контекста, или класс чужой и менять его нельзя.
Пример кода
// Comparable: один естественный порядок внутри класса
Collections.sort(students);
// Comparator: внешняя стратегия, класс не меняется
students.sort(Comparator.comparing(Student::getName)
.thenComparing(Student::getAge, Comparator.reverseOrder()));Что использовать на практике
- Comparable берите, когда у класса есть единственный очевидный порядок — например, сравнение по id.
- Comparator берите, когда порядков несколько, порядок зависит от контекста или класс чужой.
- Составные сортировки собирайте через
comparing()иthenComparing()— это читаемо и без лишнего кода.