Ключ и значения HashMap, нужно ли мне все время определять равенства и hashCode()?

У меня вопрос по поводу HashMap<Key,Values>.

Давайте представим себе такой сценарий:

У меня есть класс Person:

 Person a=new Person(int id, String fullName, int age)

Я не определял equals и hashCode в этом классе.

Предположим, я хочу сохранить 10 Person в HashMap, определенном как:

 Map<Integer,Person> hashMap=new HashMap<Integer,Person>();

Итак, я беру количество людей из базы данных, а затем делаю цикл for:

 String name = "test"; int age = "20";

 for(int i=size;i<size+10;i++)
 {
      hashMap.put(Integer.valuesOf(i), new Person(i,name+"i",age++));
 }

Я думаю, что hashMap будет использовать hashCode() класса Integer, и я получу уникальный хеш, который будет храниться в hashMap вместе с объектами Person. Если я уверен, что этот хеш будет уникальным, мне не нужно определять hashCode и equals на объекте, не так ли? или, по крайней мере, мне нужно просто определить равные, чтобы сравнивать двух человек в будущем.

Я ошибаюсь?

Начиная с Integer, equals и hashcode основаны исключительно на значении int, так что не беспокойтесь. Возвращаемое значение hashcode — это даже само значение int для класса Integer.

Arnaud 26.06.2024 15:27

Для ключей в HashMap вам нужен equals() (и метод hashCode() соответствует equals() - это означает, что для двух ключей a и b, если a.equals(b) истинно, то они должны иметь один и тот же хеш-код, но если a.equals(b) их хеш-коды должны быть разными). Для значений таких требований относительно equals() и hashCode() не существует.

Thomas Kläger 26.06.2024 15:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ключ HashMap должен соответствовать hashCode и equals. Обратите внимание, что hashCode не обязательно должен быть уникальным, но чем ближе он к нему, тем выше производительность. java.lang.Integer уже реализует и то, и другое.

Значение HashMap не обязательно должно что-либо реализовывать, хотя наличие метода equals поможет, если вы хотите использовать containsValue.

Спасибо за ваш ответ, так что в реальной программе мне следует создать еще один класс для управления ключами только класса Person, не так ли?

el moutawakil 26.06.2024 15:38

@elmoutawakil прямо сейчас, Person — твоя ценность. Это может быть разумным ключом, если вы хотите сопоставить человека с некоторыми связанными с ним данными (например, Map<Person, List<Pet>>), но на самом деле все зависит от потребностей ваших программ. Конечно, если вы решите использовать Person в качестве ключа, вам нужно будет убедиться, что вы реализовали equals и hashCode для него.

Mureinik 26.06.2024 16:03

Большое спасибо, сэр, за ваш ответ, пожалуйста, последний: когда я сохраняю ключ и значения <Person,Person> , насколько я понимаю, я сохраняю ссылку в ведре хэш-карты, чтобы не было неиспользованной памяти? Я говорю это потому, что для ключа важны только hashCode() и Equals().

el moutawakil 26.06.2024 16:07

@elmoutawakil извини, я не понимаю этот вопрос. Можете ли вы уточнить?

Mureinik 26.06.2024 16:23

ах, извините, я хотел просто сказать, что hashMap хранит ссылки на объекты, поэтому добавление Person в качестве значения, а также в качестве ключа (двойное воздействие) не приведет к увеличению использования памяти, не так ли?

el moutawakil 26.06.2024 16:31

Вместо хранения Map<Person,Person> вам следует использовать Set<Person>.

Just another Java programmer 26.06.2024 17:02

@elmoutawakil Это не будет дублировать пространство (думайте об этом как о двух ссылках на один и тот же объект, но, как сказал JustanotherJavaprogrammer, если вы сопоставляете Person с одним и тем же экземпляром Person, это просто очень неуклюжий способ иметь а Set.

Mureinik 26.06.2024 17:25

Другие вопросы по теме