Влияние оптимизации HashMap, которая кэширует хеш-код, связанный с каждой записью, в ее метод get - PullRequest
4 голосов
/ 24 сентября 2010

с.46 "Эффективная Ява" Джошуа Блох.Элемент 9: всегда переопределяйте hashCode, когда вы переопределяете равно

  • Некоторые классы PhoneNumber переопределяют equals () и не переопределяют hashCode ()
  • ". Используются два экземпляра: один используется длявставка в HashMap, и второй, равный, экземпляр используется для (попытки) поиска. "... "... Даже если два экземпляра произойдут с хэшем одного и того же сегмента, метод get почти наверняка вернет null , так как HashMap имеет оптимизацию, которая кэширует хэшкод, связанный с каждой записью, и не беспокоит проверку на равенство объектов, если хеш-коды не совпадают. "

Вопрос в том, почему get возвращает" null ", если" дваслучается, что хэши в одном и том же контейнере "?

  • какова роль (не получение правильного экземпляра) оптимизации HashMap" которая обналичивает ... "?

  • Только для случая - «два экземпляра случаются с хешем одного и того же сегмента» - что если HashMap беспокоится о «равенстве объектов, если хеш-коды не совпадают»?

Ответы [ 2 ]

4 голосов
/ 24 сентября 2010

Почему get возвращает «null», если «два экземпляра имеют хэш в одном и том же сегменте»?Какова роль (не получение правильного экземпляра) оптимизации HashMap «которая обналичивает ...»?

Ключевое предложение:

[...] не беспокоится о проверке равенства объектов, если хеш-коды не совпадают.

Так что, даже если ключи хешируются в одно и то же ведро, .equalsможет не вызываться (из-за оптимизации кэширования) для соответствующего элемента (поскольку даже хеш-коды не совпадают).Таким образом, даже если соответствующий элемент находится в одном и том же сегменте, он никогда не может сравниваться через .equals и, следовательно, не «найден».

Только для случая - «дваСлучаи случаются с хэшем в том же контейнере "- что если HashMap беспокоится о" равенстве объектов, если хеш-коды не совпадают "?* иметь эту оптимизацию, и на самом деле сделал проверку .equals на всех элементах в соответствующем сегменте и , если два хэша оказались с хешем одного и того же сегмента, то метод get будетверните правильный элемент.(Но это было бы чистой удачей, так как если объекты не равны, то нет никакой гарантии, что эти два хэша будут отображаться в одно и то же ведро в первую очередь.)

1 голос
/ 25 сентября 2010

почему get возвращает "null", если "два экземпляра имеют хеш-код одного и того же сегмента"

Это будет происходить только в том случае, если хеш-коды будут неравнымиЭто может быть сделано, потому что по контракту hashCode () неравные hashCodes подразумевают неравные объекты.(Обратите внимание, что обратное неверно: языковые юристы, обратите внимание.)

...