Понимание содержит метод Java HashSet

Вопрос о пользователе java HashSet

Set<User> s = new HashSet<User>();
User u = new User();
u.setName("name1");
s.add(u);
u.setName("name3");
System.out.println(s.contains(u));

Может кто-нибудь объяснить, почему этот код выводит false? Кроме того, этот код даже не вызывает метод equals пользователя. Но, согласно источникам HashSet и HashMap, это нужно назвать. Метод равно Пользователю просто вызывает равных по имени пользователя. Метод hashCode возвращает hashCode имени пользователя

Ответ 1

Если метод хеш-кода основан на поле name, и вы затем изменяете его после добавления объекта, то вторая проверка contains будет использовать новое значение хэша и не будет находить объект, который вы были находясь в поиске. Это связано с тем, что HashSet первый поиск по хэш-коду, поэтому они не будут беспокоиться о вызове equals, если этот поиск завершится с ошибкой.

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

В общем, вы никогда не должны обновлять объект после добавления его в HashSet, если это изменение также изменит его хэш-код.

Ответ 2

Поскольку ваш новый User имеет другой хэш-код, HashSet знает, что он не равен.

HashSets сохраняет свои товары в соответствии с их хэш-кодами.
HashSet будет вызывать только equals, если он найдет элемент с тем же хэш-кодом, чтобы убедиться, что оба элемента на самом деле равны (в отличие от хеш-коллизии)