HashSet — это реализация интерфейса Set на основе HashMap. Хранит уникальные элементы без дубликатов с быстрым O(1) поиском.
📦 Базовая структура
HashSet — это тонкая обёртка над HashMap:
public class HashSet<E> {
private transient HashMap<E, Object> map;
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
}▪️ Главные особенности
→ Элементы хранятся как ключи HashMap.
→ Значения — константа PRESENT (заглушка).
→ O(1) для add, remove, contains (как у HashMap).
→ Не гарантирует порядок элементов.
→ Не допускает дубликаты (ключи Map уникальны).
🔹 Внутренняя структура идентична HashMap:
HashMap<E, PRESENT>:
table[]:
[0]: null
[1]: Entry(key="B", value=PRESENT) → Entry(key="M", value=PRESENT)
[2]: Entry(key="A", value=PRESENT)
[3]: Entry(key="C", value=PRESENT)
[4]: null
...
Set элементы = ключи HashMap
Значения = PRESENT (игнорируются)
🔹 Все операции делегируются HashMap
➕ add(E element) — добавление
1. Вызывается map.put(element, PRESENT).
2. HashMap вычисляет hash(element).
3. Определяется бакет по индексу.
4. Проверяется наличие ключа через equals():
— Если есть: возвращается false (дубликат не добавлен).
— Если нет: создаётся Entry, возвращается true.
Сложность: O(1) в среднем.
🔎 contains(Object o) — проверка наличия
1. Вызывается map.containsKey(o).
2. HashMap ищет ключ по hash и equals().
3. Возвращается true/false.
Сложность: O(1) в среднем.
➖ remove(Object o) — удаление
1. Вызывается map.remove(o).
2. HashMap находит и удаляет ключ.
3. Возвращается true если элемент был, иначе false.
Сложность: O(1) в среднем.
⚖️ Важные нюансы
HashSet НЕ наследует HashMap, а содержит его как поле. Все методы делегируют вызовы.
HashSet допускает один null (так как HashMap допускает null key).
Элементы ДОЛЖНЫ корректно реализовывать hashCode() и equals().
Для concurrent доступа:
— Collections.synchronizedSet(new HashSet<>());
— ConcurrentHashMap.newKeySet();
— CopyOnWriteArraySet (для read-heavy нагрузки).
Как у HashMap, можно указать при создании. Это помогает избегать resize операций.
→ Быстрой проверки наличия
→ Автоматического удаления дубликатов
→ Операций над множествами. Объединение, пересечение, разность за O(n).
→ Максимальной производительности без затрат на сортировку.
Ставьте 🔥, если хотите ещё разбор.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍2👏1