Ответ
Да, интерфейс Set в Java гарантирует, что коллекция не содержит дубликатов элементов. Это основное контрактное отличие от List.
Механизм обеспечения уникальности:
Реализации Set (такие как HashSet, TreeSet) используют для проверки уникальности комбинацию методов hashCode() и equals().
- При добавлении элемента сначала вычисляется его хэш-код (
hashCode()). - По хэш-коду определяется «корзина» (bucket), где должен находиться элемент.
- Если в этой корзине уже есть элементы, происходит поочередное сравнение нового элемента с существующими через
equals(). Еслиequals()возвращаетtrueдля какого-либо элемента, добавление не происходит.
Пример и важное замечание:
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
boolean isAdded = set.add("apple"); // isAdded = false, элемент не добавлен
System.out.println(set); // [apple, banana] (порядок не гарантирован)
Критически важно: Для корректной работы Set с пользовательскими объектами вы должны корректно переопределять equals() и hashCode(), соблюдая их контракт. Иначе уникальность не будет обеспечена.
// ПЛОХО: Класс без переопределенных equals/hashCode
class BadKey {
String id;
}
Set<BadKey> badSet = new HashSet<>();
badSet.add(new BadKey("a"));
badSet.add(new BadKey("a")); // ДОБАВИТСЯ, т.к. это разные объекты по ==