Какие требования предъявляются к объекту-ключу для корректной работы TreeMap в Java?

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

Ответ

Для корректной работы TreeMap ключи должны быть сравнимыми. Это достигается одним из двух способов:

  1. Реализация интерфейса Comparable самим классом ключа.
  2. Передача внешнего Comparator в конструктор TreeMap.

Ключевые требования к сравнению:

  • Согласованность с equals: Метод compareTo (или compare) должен возвращать 0 только тогда, когда equals возвращает true. Нарушение этого контракта приведет к противоречивому поведению коллекции, реализующей интерфейс SortedMap (как TreeMap).
  • Транзитивность: Если a.compareTo(b) > 0 и b.compareTo(c) > 0, то должно выполняться a.compareTo(c) > 0.

Пример корректного класса-ключа:

class Person implements Comparable<Person> {
    private String name;
    private int age;

    // Конструктор, геттеры...

    @Override
    public int compareTo(Person other) {
        // Сначала сравниваем по имени, затем по возрасту
        int nameCompare = this.name.compareTo(other.name);
        if (nameCompare != 0) {
            return nameCompare;
        }
        return Integer.compare(this.age, other.age);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return age == person.age && name.equals(person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
// Использование
TreeMap<Person, String> map = new TreeMap<>();