LinkedHashSet — это реализация интерфейса Set из пакета java.util, которая сохраняет порядок вставки элементов. Это гибрид между HashSet (быстрый поиск) и списком (предсказуемый порядок итерации).
📦 Базовая структура
LinkedHashSet — это тонкая обёртка над LinkedHashMap. Внутри:
— Все элементы хранятся как ключи в LinkedHashMap.
— Значения — константа PRESENT (заглушка Object).
— Порядок поддерживается через двусвязный список узлов.
Главная особенность:
— O(1) для add, remove, contains (как у HashSet).
— Предсказуемый порядок итерации (порядок вставки).
— Немного больше памяти, чем HashSet (~25% overhead на связи).
🔍 Как устроено хранение
LinkedHashSet полностью делегирует работу LinkedHashMap, а тот устроен так:
Entry<K,V> — узел хранения:
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before; // предыдущий в порядке вставки
Entry<K,V> after; // следующий в порядке вставки
}
```
### **Двойная структура:**
1. **Хэш-таблица** (массив бакетов):
- Быстрый доступ по хэшу → O(1).
- Разрешение коллизий через цепочки/деревья.
2. **Двусвязный список**:
- Связывает все элементы в порядке добавления.
- Голова списка: `head` (первый добавленный).
- Хвост списка: `tail` (последний добавленный).
**Визуализация:**
```
Хэш-таблица:
Bucket[0]: null
Bucket[1]: Entry("B") ----→ Entry("F")
Bucket[2]: Entry("A")
Bucket[3]: Entry("C")
Двусвязный список (порядок вставки):
head → Entry("A") ⇄ Entry("B") ⇄ Entry("C") ⇄ Entry("F") ← tail
➕ add(E element) — добавление
1. Вычисляется хэш элемента: hash(e).
2. Определяется индекс бакета: index = hash & (n-1).
3. Проверяется наличие элемента в бакете:
— если есть → возвращается false (дубликат).
— если нет → создаётся новый Entry.
4. Новый Entry:
— добавляется в бакет хэш-таблицы.
— связывается с tail в двусвязном списке.
— обновляется tail = newEntry.
5. При необходимости таблица расширяется (load factor > 0.75).
Сложность: O(1) в среднем.
🔎 contains(Object o) — проверка наличия
1. Вычисляется хэш объекта.
2. Проверяется соответствующий бакет.
3. Сравнивается через equals().
4. Двусвязный список НЕ используется для поиска.
Сложность: O(1) в среднем.
➖ remove(Object o) — удаление
1. Находится Entry в хэш-таблице по хэшу.
2. Узел удаляется из бакета.
3. Узел отсоединяется от двусвязного списка.
4. Обновляются ссылки head/tail при необходимости.
Сложность: O(1) в среднем.
⚖️ Важные нюансы
1. Наследование от HashSet
Наследует поведение HashSet, но меняет внутреннюю реализацию. Конструкторы создают LinkedHashMap вместо HashMap.
2. Null элементы
Один null может быть добавлен (как в HashSet).
3. Не потокобезопасен
Для многопоточного доступа требуется внешняя синхронизация. Альтернатива: CopyOnWriteArraySet (но без хэш-таблицы).
4. Equals и hashCode
Сравнивает содержимое, игнорируя порядок:
5. Capacity и Load Factor
Начальные значения: Capacity 100, load factor 0.75
Начальная ёмкость должна учитывать ожидаемый размер.
При достижении threshold (capacity × load factor) происходит resize.
1. Порядок не важен
Используйте HashSet — проще и немного быстрее (меньше overhead).
2. Нужна сортировка
Используйте TreeSet — автоматическая сортировка по Comparator/Comparable.
3. Многопоточный доступ
Используйте ConcurrentHashMap.newKeySet() или CopyOnWriteArraySet. Или оборачивайте: Collections.synchronizedSet().
4. Критична минимизация памяти:
HashSet использует меньше памяти (~20% экономии).
🔗 Документация: JavaDoc (Java 17)
Ставьте 🔥, если хотите разбор TreeSet!
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍4🎉1
Forwarded from Библиотека задач по Java | тесты, код, задания
Что произойдёт при запуске приложения с таким классом?
Anonymous Quiz
27%
Не запустится, так как нельзя использовать обе эти аннотации на одном классе
44%
Запустится, будет зарегистрирован один бин
7%
Запустится, но Spring не создаст ни одного бина из-за конфликта
8%
Запустится, будет зарегистрировано два разных бина: один с @Component, другой с @Service
14%
Посмотреть ответ
🔥5👍3❤1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁24💯2🔥1👾1
⚙️ Byte Buddy
Byte Buddy — это библиотека для runtime генерации и модификации байт-кода Java. В отличие от классических ASM или Javassist, она предлагает type-safe API и не требует глубоких знаний JVM internals.
📌 Что умеет Byte Buddy
— Создаёт классы и прокси на лету без написания байт-кода вручную
— Перехватывает методы, добавляет логирование, метрики или трейсинг без изменения исходного кода
— Работает как Java-агент для инструментации существующих классов (например, для APM-систем)
— Интегрируется с Mockito, Hibernate и другими фреймворками под капотом
— Поддерживает все современные Java-фичи (records, sealed classes, pattern matching)
🧠 Особенно полезно для
Создания динамических прокси с кастомным поведением, написания собственных фреймворков или библиотек с AOP-логикой, инструментации приложений для мониторинга (как делают Datadog, New Relic), тестирования с подменой реализаций классов.
Byte Buddy даёт мощь низкоуровневой манипуляции классами, но с человеческим API. Если вы когда-то смотрели на ASM и думали "это слишком сложно" — попробуйте Byte Buddy.
🔗 Byte Buddy на GitHub
🐸 Библиотека джависта
#Enterprise
Byte Buddy — это библиотека для runtime генерации и модификации байт-кода Java. В отличие от классических ASM или Javassist, она предлагает type-safe API и не требует глубоких знаний JVM internals.
— Создаёт классы и прокси на лету без написания байт-кода вручную
— Перехватывает методы, добавляет логирование, метрики или трейсинг без изменения исходного кода
— Работает как Java-агент для инструментации существующих классов (например, для APM-систем)
— Интегрируется с Mockito, Hibernate и другими фреймворками под капотом
— Поддерживает все современные Java-фичи (records, sealed classes, pattern matching)
🧠 Особенно полезно для
Создания динамических прокси с кастомным поведением, написания собственных фреймворков или библиотек с AOP-логикой, инструментации приложений для мониторинга (как делают Datadog, New Relic), тестирования с подменой реализаций классов.
Byte Buddy даёт мощь низкоуровневой манипуляции классами, но с человеческим API. Если вы когда-то смотрели на ASM и думали "это слишком сложно" — попробуйте Byte Buddy.
🔗 Byte Buddy на GitHub
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1🔥1🤔1