Начальная емкость и коэффициент нагрузки - два параметра, которые влияют на производительность HashMap
.
Коэффициент загрузки по умолчанию (.75
) предлагает хороший компромисс между затратами времени и пространства. Более высокие значения уменьшают объем служебных данных, но увеличивают стоимость поиска.
Когда элемент добавляется в HashMap
, он присваивается ковшим на основе значения, полученного из его hashCode
, и размера ковша HashMap
.
Чтобы определить ведро для любого, используйте хэш-карту key.hashCode()
и выполните некоторую операцию:
Bucket (index) = HashMap.indexFor(HashMap.hash(key.hashCode()),
entryArray.length)
Когда количество записей в хэш-карте превышает произведение коэффициента загрузки и текущей емкости, хэш-карта повторно просматривается (внутренние структуры данных перестраиваются), так что хэш-карта имеет примерно вдвое больше количества ковшей.
Когда вы переадресовываете и перемещаете все в новое место (ведро и т.д.), то старые элементы снова перезаписываются и сохраняются в новом ковше в соответствии с их новыми хэш-кодами. Старое пространство, которое было выделено для хранения элементов, - это сбор мусора.
Если два потока в то же время обнаружили, что теперь HashMap
нуждается в повторной калибровке, и оба они попытаются изменить размер, это может привести к состоянию гонки в HashMap
.
В процессе переопределения HashMap
элемент в ведре, который хранится в связанном списке, изменяется во время перехода в новый ведро, потому что java HashMap
не добавляет новый элемент в хвост вместо он добавляет новый элемент во главе, чтобы избежать перемещения хвоста. Если состояние гонки произойдет, вы получите бесконечный цикл.
У меня есть следующие вопросы:
- Почему связанный список для каждого ведра меняется на переход на новое ведро?
- Как состояние гонки может привести к бесконечной петле?
- Как увеличить количество ведер, уменьшающих ожидания поиска время?
- Элементы, находящиеся в одном ведре, все равно будут вместе ковш после повторного рейса?