2010-09-24 1 views
4

с. 46 «Эффективная Java» Джошуа Блох. Пункт 9: Always переопределить хэш-код при переопределении равноВлияние оптимизации HashMap, которое кэширует хэш-код, связанный с каждой записью, с его методом получения

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

Вопросы: - почему 'get' вернет 'null', если «два экземпляра происходят с хэшем в том же ведро»?

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

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

ответ

4

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

Ключевая фраза является

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

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

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

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

+1

@ajoobe вы сказали: «Таким образом, даже если соответствующий элемент находится в одном ведре, он никогда не может сравниться через .equals и, следовательно, найденный"." , Как это возможно, если у них разные хэш-коды(), как они могут попасть в одно и то же ведро в первую очередь? Можете ли вы прояснить, пожалуйста? – Geek

+1

Хэш-код может быть произвольным int, поэтому каждый хеш-код не может иметь собственный ведро. Следовательно, некоторые объекты с разными хэш-кодами оказываются в одном и том же ковше. – aioobe

+0

@ajoobe: Большое вам спасибо, я был так смущен объектами с разными хэш-кодами в том же ведре. Не могли бы вы дать мне ссылку, в которой подробно объясняется, как управляются операции, такие как изменение размера? –

1

почему «получить» вернет «нулевой» если « два экземпляра произойдет хэш в же ведро»

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