compareTo(), который тихо теряет элементы в TreeSet

TreeSet и TreeMap не используют equals() и hashCode() для определения уникальности. Единственный критерий — результат compareTo() (или Comparator, если он передан в конструктор). Этот вопрос почти всегда всплывает как «а как TreeSet проверяет дубликаты».

Если compareTo() сравнивает объекты только по одному полю, а не по всем значимым, TreeSet считает равными два логически разных объекта. Второй add() тихо возвращает false — исключения нет, дубликат просто не попадает в сет.

class Employee implements Comparable { String name; int salary;

public int compareTo(Employee o) { return Integer.compare( this.salary, o.salary); } }

Set set = new TreeSet<>(); set.add(new Employee("Иван", 100000)); set.add(new Employee("Пётр", 100000)); // set.size() == 1

Юнит-тест почти никогда не поймает эту потерю, если явно не проверяет size() после вставки нескольких объектов с одинаковым значением поля сравнения. add() возвращает boolean, но в бизнес-коде этот результат обычно игнорируют.

Для TreeSet и TreeMap правильный compareTo() — не про сортировку, а про то, что считается дубликатом.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки