Есть ли недостатки в использовании произвольных объектов в качестве ключей карты в Java?
-
10-07-2019 - |
Вопрос
В моем приложении есть два типа объектов, где каждому объекту одного типа соответствует ровно один объект другого типа.
Очевидным выбором для отслеживания этих отношений является Map<type1, type2>
, как HashMap.Но что-то я подозрительно.Могу ли я использовать объект в качестве ключа на Карте, передавать его, хранить в другой коллекции и в любое время извлекать его партнера из Карты?
После создания объекта я передаю только идентификатор, верно?Так что, наверное, здесь нет проблем.Что если я сериализую и десериализую ключ?
Есть еще какие-нибудь предостережения?Должен ли я использовать что-то еще для корреляции пар объектов, например число, которое я генерирую сам?
Решение
.equals()
и .hashCode()
HashMap
, пока он используется в качестве ключа Другие советы
У меня есть два вида объектов в моем приложение, где каждый объект одного вид имеет ровно один соответствующий объект другого вида.
Это действительно звучит как отношение has-a и, следовательно, может быть реализовано с использованием простого атрибута.
Это зависит от реализации выбранной вами карты:
Хэшмап использует равно() и хэш-код().По умолчанию (в Object) они основаны на идентификаторе объекта, который будет работать нормально, если вы не сериализуете/десериализуете.При правильной реализации методовquals() и hashCode() на основе содержимого объекта у вас не возникнет проблем, если вы не измените его, пока он является ключом в хэш-карте.
ДеревоКарта использует по сравнению с().Реализации по умолчанию не существует, поэтому вам необходимо ее предоставить.Применяются те же ограничения, что и для реализации hashCode() и equals() выше.
Вы можете использовать стандартную карту, но при этом вы будете сохранять сильные ссылки на ваши объекты на карте. Если на ваши объекты ссылаются в другой структуре, и вам нужна карта, чтобы просто связать их вместе, подумайте об использовании WeakHashMap.
И кстати, вам не нужно переопределять equals и hashCode, если вам не нужно рассматривать несколько экземпляров объекта как равные ...
Могу ли я использовать объект в качестве ключа на карте, передать его, поместить его в другую коллекцию и в любое время получить своего партнера с карты?
Да, здесь вообще нет проблем.
После создания объекта все, что я передаю, это идентификатор, верно? Так что, вероятно, нет проблем там. Что если я сериализую и десериализую ключ?
Правильно, вы только передаете ссылку - все они будут указывать на один и тот же реальный объект. Если вы сериализуете или десериализуете объект, это создаст новый объект. Однако, если ваш объект правильно реализует функции equals и hashCode, вы все равно сможете использовать новый десериализованный объект для извлечения элементов с карты.
Любые другие предостережения? Должен ли я использовать что-то еще для сопоставления пар объектов, например, число, которое я генерирую сам?
Что касается предупреждений, да, вы не можете изменить ничего, что могло бы вызвать изменение хэш-кода объекта, пока объект находится на карте. Р>
Любой объект может быть ключом карты. Здесь важно убедиться, что вы переопределяете .equals () и .hashCode () для любых объектов, которые будут использоваться в качестве ключей карты.
Причина, по которой вы делаете это, заключается в том, что если вы этого не сделаете, equals будет пониматься как объектное равенство, и единственный способ найти " equal " Ключи карты должны иметь дескриптор самого исходного объекта.
Вы переопределяете хеш-код, потому что он должен быть согласован с равными. Это сделано для того, чтобы объекты, которые вы определили как равные хешу, одинаково.
Точки сбоя - это хэш-код и функции равенства. Если они не дают последовательных и правильных возвращаемых значений, карта будет вести себя странно. Эффективная Java имеет целый раздел и настоятельно рекомендуется. р>
Вы можете рассмотреть коллекцию Google. BiMap .