Ответ
В Java 8 HashMap был значительно оптимизирован для обработки коллизий и итерации.
Основные изменения:
-
Переход на красно-черное дерево в корзинах с коллизиями
- Было: При коллизиях (одинаковый
hashCodeдля разных ключей) элементы в одной корзине хранились в односвязном списке. В худшем случае поиск былO(n). - Стало: Когда размер списка в корзине превышает порог (
TREEIFY_THRESHOLD = 8), он преобразуется в красно-черное дерево. Поиск в худшем случае становитсяO(log n). При уменьшении размера дерево снова преобразуется в список.
- Было: При коллизиях (одинаковый
-
Улучшение хеш-функции
- Изменен алгоритм вычисления индекса корзины для снижения вероятности коллизий при плохих хеш-кодах.
-
Оптимизация итераторов
- Введен улучшенный
Spliteratorдля более эффективного параллельного обхода.
- Введен улучшенный
Пример и последствия:
HashMap<KeyWithBadHash, Integer> map = new HashMap<>();
// Если множество ключей возвращает один hashCode(),
// в Java 7 поиск по map.get() деградировал до O(n).
// В Java 8 при >8 коллизий в корзине поиск будет O(log n).
Итог: Эти изменения защитили HashMap от атак на производительность через искусственное создание коллизий и улучшили работу в высоконагруженных сценариях.