Как интерфейсы Comparable и Comparator используются для сортировки коллекций в Java?

«Как интерфейсы Comparable и Comparator используются для сортировки коллекций в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оба интерфейса определяют порядок элементов, но служат разным целям и используются по-разному в 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стратегия сортировки, отдельная от объекта ("вот правило, по которому нужно сравнивать эти объекты").