HashMapсодержит определенное количество ведер. Он используется, hashCodeчтобы определить, в какую корзину их поместить. Для простоты представьте его как модуль.
Если наш хэш-код - 123456 и у нас 4 сегмента, 123456 % 4 = 0значит, элемент попадает в первую корзину, Bucket 1.

Если наша функция хэш-кода хороша, она должна обеспечивать равномерное распределение, поэтому все сегменты будут использоваться примерно одинаково. В этом случае корзина использует связанный список для хранения значений.

Но нельзя полагаться на людей в реализации хороших хэш-функций. Люди часто пишут плохие хеш-функции, что приводит к неравномерному распределению. Также возможно, что нам просто не повезло с нашими вводами.

Чем менее равномерно это распределение, тем дальше мы продвигаемся от операций O (1) и тем ближе мы приближаемся к операциям O (n).
Реализация Hashmap пытается смягчить это, организовывая некоторые сегменты в деревья, а не в связанные списки, если сегменты становятся слишком большими. Это то TREEIFY_THRESHOLD = 8, для чего. Если ведро содержит более восьми предметов, оно должно стать деревом.

Это дерево - красно-черное дерево. Сначала он сортируется по хеш-коду. Если хэш-коды совпадают, он использует compareToметод, Comparableесли объекты реализуют этот интерфейс, иначе хэш-код идентификации.
Если записи удаляются с карты, количество записей в корзине может уменьшиться, так что эта древовидная структура больше не нужна. Вот для чего UNTREEIFY_THRESHOLD = 6это нужно. Если количество элементов в корзине становится меньше шести, мы можем вернуться к использованию связанного списка.
Наконец, есть файл MIN_TREEIFY_CAPACITY = 64.
Когда хэш-карта увеличивается в размере, она автоматически меняет размер, чтобы иметь больше сегментов. Если у нас есть небольшая хеш-карта, вероятность того, что мы получим очень полные корзины, довольно высока, потому что у нас не так много разных корзин, в которые можно было бы поместить материал. Намного лучше иметь большую хэш-карту с большим количеством менее заполненных корзин. Эта константа в основном говорит, что нельзя начинать превращать ведра в деревья, если наша хэш-карта очень маленькая - вместо этого следует изменить размер, чтобы стать больше.
Чтобы ответить на ваш вопрос о приросте производительности, эти оптимизации были добавлены для улучшения худшего случая. Я только предполагаю, но вы, вероятно, увидите заметное улучшение производительности из-за этих оптимизаций, только если бы ваша hashCodeфункция была не очень хорошей.
String, имеют гораздо большее пространство значений, чемintхэш-код, поэтому столкновения неизбежны. Теперь это зависит от фактических значений, таких как фактическиеStrings, которые вы вводите в карту, получаете ли вы равномерное распределение или нет. Плохое распределение может быть результатом просто неудачи.