2012-02-04 3 views
3

Есть ли реализация java.util.Map, которая не использует HashCode?Реализация Java Map не основана на HashCode

У меня следующая проблема:

  1. хранить объект, связанный с другим объектом на HashMap;
  2. Измените свойство из ключевого объекта, используемого на шаге 1;
  3. Поскольку хэш-код используется для хранения ключей на регулярной реализации HashMap, когда я выполняю get() на HashMap, я получаю пустой, потому что старый объект хэш-код отличается на шаге 1.

ли есть решение для этого? Или я должен использовать только неизменяемые поля для моих методов equals/hashCode?

+1

Как хэш-карта знает, что вы только что изменили свой внутренний ключ? Удалите и повторно вставьте или не используйте изменяемые ключи для начала. – Voo

+0

это была не моя идея ... моя цель - использовать impl, который просто использует equals вместо hashmap, даже если не оптимизирован. –

ответ

8

IdentityHashMap использует идентификатор объекта вместо hashCode; однако это означает, что вам требуется исходный объект, используемый в качестве ключа для получения значения карты. Другие варианты будут переопределять хэш-код, чтобы исключить изменяемые части объекта, или - если вы не можете переопределить хэш-код по какой-либо причине - оберните объект в другой объект, который обеспечивает стабильный hashCode.,

6

Вам будет рекомендовано использовать неизменяемый ключ и повторно вставить пару ключ/значение в карту, а не мутировать ключ на месте. Как вы обнаружили, это просто приводит к странным ошибкам.

Если это не вариант для вас, посмотрите, можете ли вы игнорировать свойство mutable в методе hashCode(), чтобы хеш-код не менялся. Если это единственное свойство класса, это не очень хорошая идея.

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

+0

FYI, если реализация compareTo также зависит от изменяемого поля, тогда вы можете получить то же самое результаты с treemap. equals, compareTo и hashCode должны быть постоянными (по своему поведению) в течение всего жизненного цикла объекта. – luke

+0

@ luke: Да, я верю, что сказал это. – skaffman

0

Переопределите методы equals и hashCode, если вы не хотите оригинальной реализации.

0

Все ассоциативные контейнеры используют сравнительный или хеш-код, поэтому я хотел бы рекомендовать вам использовать неизменяемые поля для методов equals()/hashCode().

0

Как насчет удаления и добавления его снова?

На шаге 2 Вы можете удалить элемент, добавленный на шаге 1, и снова добавить его с новыми последними наборами свойств. Таким образом, когда вы попытаетесь попасть на Шаг 3, вы найдете его.

Попробуйте.

+0

Хотя это и работает, я также думаю, что это наглядно демонстрирует недостаток в дизайне. Другим объектам или логике не нужно знать об этих деталях реализации и обходных решениях. –

1

Все Карты должны использовать неизменяемые объекты для ключей. True для Python; true для Java.

Если вы реализуете equals и hashCode, используя только неизменяемые поля, вы должны быть в порядке.

0

Я думаю, измените ключевой объект на карте не является хорошей практикой.

Но если вы действительно этого хотите, вы можете переопределить hashCode() и не забудьте переопределить метод equal().

Смежные вопросы