Если мы переопределяем equals(), то обязаны переопределить hasCode().
Причем в обоих методах желательно использовать одни и те же поля класса.
Причем, если equals() дает true, то и hashCode() должен быть одинаковым.
Возникает вопрос: а почему бы при переопределении equals() тогда просто не сравнивать hashCode()?
Если для двух объектов hashCode возвращает одинаковое значение - это не означает, что это тот же самый объект.
Но если equals для двух объектов возвращает true, то их hashCode будет одинаковый.
Алгоритм расчёта хэшкода в классе Object не учитывает содержимое класса и реализован так, что при каждом запуске программы, даже у экземпляра класса с одним и тем же содержимым хэш будет разным.
Поэтому, если Вы будете сравнивать экземпляры класса по хэшкоду без переопределения метода hashCode() у Вас всегда будет false.
Собственно, из-за этого и рекомендуется переопределять метод hashCode().
Метод equals() отвечает за определение эквивалентности объектов. Но, и он в классе Object не идеален, т.к. сравнивает лишь ссылки на объекты без учёта их содержимого. Потому его то же рекомендуют переопределять.
Как программист будет определять эквивалентность двух объектов с учётом их содержимого в equals() по большому счёту его личное дело. Только при вычислении хэшкода возможны, т.н. коллизии. Когда два разных объекта имеют одинаковый хэш. По этой причине одинаковые хэшкоды двух и более объектов, ещё не гарантия их эквивалентности. Поэтому при переопределении equals() просто сравнивать hashCode() нельзя.
Алгоритмы получения хеш не гарантируют уникальности получаемых значений для разных входных данных. Например слова "Siblings" и "Teheran" имеют идентичный хеш:
jshell> "Siblings".hashCode()
$7 ==> 231609873
jshell> "Teheran".hashCode()
$8 ==> 231609873
jshell> Objects.equals("Teheran", "Siblings")
$10 ==> false
Это пример коллизии хеш-функции, дело в том, что хеш-функция должна из любого входящего значения произвольной длинны вернуть число ограниченной длинны, в случае метода hashCode это 4-х байтовое целое число, которое может принимать одно из 2^32 возможных значений (это чуть больше четырех миллиардов).
Основным требованием к хэш-функции является равномерность распределения возвращаемых значений при случайном выборе аргументов. Но это не исключает возникновение коллизий. Например большинство сайтов не хранит в базе пароли пользователей в открытом виде, а только их хеш, полученный, например, посредством алгоритма md5. Этот алгоритм вернет 128-битное число, а это значит, что подобрать пароль будет возможно при переборе 2^128 возможных вариантов. Причем полученное, при переборе, входное значение не обязательно будет совпадать с фактическим паролем, но иметь точно такой же хеш.
Метод equals в java объектах как раз и нужен чтоб исключить влияние коллизий на нахождение элементов в коллекциях использующих hashCode и equals, это такие коллекции как HashMap и HashSet. Они используют метод hashCode для определения "места" где должен находится объект, в случае коллизии объекты имеющие идентичный хеш помещаются в список. Поиск среди таких объектов будет осуществляться перебором с вызовом метода equals для каждого элемента списка.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости