Изменение хеш-кода объекта, хранящегося в хэш-коллекции - PullRequest
2 голосов
/ 03 марта 2011

У меня есть коллекция объектов на основе хеша, например HashSet или HashMap.С какими проблемами я могу столкнуться, когда реализация hashCode() такова, что она может меняться со временем, поскольку она вычисляется из некоторых изменяемых полей?

Как это влияет на Hibernate?Есть ли причина, по которой hashCode() идентификатор объекта по умолчанию является плохим?Все еще не сохраненные объекты имеют id = 0, если это имеет значение.

Какова разумная реализация hashCode для объектов, отображаемых в Hibernate?Однажды установленный идентификатор является неизменным, но это не так в момент сохранения сущности в базу данных.

Меня не беспокоит производительность HashSet с дюжиной сущностей с ключом = 0.Меня волнует, безопасно ли для моего приложения и Hibernate использовать ID в качестве хеш-кода, потому что идентификатор изменяется при его создании при сохранении.

Ответы [ 5 ]

3 голосов
/ 03 марта 2011

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

  • Вещи, которые вы кладете в коллекцию, похоже, уже не существует
  • Получение чего-то, что отличается от того, что вы просили

Это, безусловно,не то, что вы хотите.Поэтому я рекомендую делать хеш-код только из неизменяемых полей.Обычно это делается путем создания полей final и установки их значений в конструкторе.

3 голосов
/ 03 марта 2011

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

Возвращение идентификатора объекта само по себе неплохо, но если многие из них имеют id = 0, как вы упомянули, это снизит производительность хеш-таблицы: все объекты с одинаковым хеш-кодом попадают в одну корзину, поэтомуВаша хеш-таблица теперь не лучше, чем линейный список.

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

1 голос
/ 03 марта 2011
0 голосов
/ 03 марта 2011

Javadoc специально говорит, что встроенные Коллекции не поддерживают это. Так что не делай этого.

0 голосов
/ 03 марта 2011

Не меняйте хеш-код элементов в коллекции на основе хеша после пут.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...