Гарантирует ли интерфейс Set в Java уникальность элементов?

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

Ответ

Да, интерфейс Set гарантирует отсутствие дубликатов элементов в коллекции. Уникальность определяется на основе методов equals() и hashCode() (или compareTo()/Comparator).

Как обеспечивается уникальность в основных реализациях:

  • HashSet: Использует hashCode() для быстрого поиска корзины и equals() для точной проверки внутри корзины.
  • TreeSet: Использует compareTo() (натуральный порядок) или Comparator. Элементы считаются дубликатами, если compareTo() возвращает 0.
  • LinkedHashSet: Сохраняет порядок вставки, но для проверки уникальности использует ту же логику, что и HashSet.

Пример:

Set<String> set = new HashSet<>();
set.add("apple");
set.add("apple"); // Не добавится, так как equals() вернет true
System.out.println(set.size()); // 1

Важное предупреждение: Если объект, уже находящийся в HashSet, изменяется так, что меняется его hashCode(), этот объект может стать "потерянным" (невозможным для поиска), что нарушит контракт коллекции. Для ключей рекомендуется использовать immutable объекты.