Ответ
Оба интерфейса определяют порядок элементов, но служат разным целям и используются по-разному в API коллекций.
Comparable<T> (Внутренний, естественный порядок)
- Цель: Определяет естественный (нативный) порядок сортировки для объектов класса. Класс сам решает, как его экземпляры должны сравниваться.
- Метод:
int compareTo(T o) - Использование в коллекциях: Автоматически используется методами, которые сортируют или упорядочивают, если не указан явный
Comparator.Collections.sort(List<T>)Arrays.sort(T[])- Элементы в
TreeSet<T>или как ключи вTreeMap<K, V>.
class Person implements Comparable<Person> {
private String name;
@Override
public int compareTo(Person other) {
return this.name.compareTo(other.name); // Естественный порядок по имени
}
}
// Использование:
List<Person> people = ...;
Collections.sort(people); // Сортировка использует compareTo
Comparator<T> (Внешний, гибкий порядок)
- Цель: Определяет альтернативные или внешние правила сортировки. Позволяет сортировать объекты по разным критериям, не изменяя их исходный класс.
- Метод:
int compare(T o1, T o2) - Использование в коллекциях: Передается как аргумент в методы сортировки или конструкторы упорядоченных коллекций.
Collections.sort(List<T>, Comparator<T>)TreeSet<T>(Comparator<T>)
// Компаратор для сортировки по возрасту
Comparator<Person> byAge = (p1, p2) -> Integer.compare(p1.getAge(), p2.getAge());
// Использование с разными правилами:
Collections.sort(people, byAge);
Collections.sort(people, byAge.reversed()); // Обратный порядок
Ключевое отличие: Comparable — это свойство самого объекта ("я знаю, как меня сравнивать"), а Comparator — стратегия сортировки, отдельная от объекта ("вот правило, по которому нужно сравнивать эти объекты").