Методы equals() и hashCode() в Java связаны между собой и используются для работы с хэш-таблицами и коллекциями, такими как HashMap, HashSet и Hashtable. Давайте рассмотрим их подробнее.
Метод equals() Метод equals() используется для сравнения двух объектов на равенство. Он является частью класса Object и может быть переопределен в пользовательских классах для определения собственной логики сравнения объектов. По умолчанию, метод equals() сравнивает объекты по ссылке, то есть проверяет, являются ли они одним и тем же объектом в памяти.
Метод hashCode() Метод hashCode() используется для получения целочисленного значения, называемого хэш-кодом, для объекта. Хэш-код представляет собой числовое значение, которое используется для оптимизации поиска и сравнения объектов в хэш-таблицах и коллекциях. Хэш-код должен быть одинаковым для двух объектов, которые равны согласно методу equals(). Однако, два объекта с одинаковым хэш-кодом не обязательно должны быть равными.
Связь между equals() и hashCode() В Java существует следующее правило: если два объекта равны согласно методу equals(), то их хэш-коды должны быть равными. Это означает, что если вы переопределяете метод equals() в своем классе, вы также должны переопределить метод hashCode() таким образом, чтобы он возвращал одинаковое значение для равных объектов.
Почему это важно? Потому что многие коллекции в Java, такие как HashMap и HashSet, используют хэш-коды для оптимизации поиска и сравнения объектов. Если вы не переопределите метод hashCode(), то объекты, которые равны согласно методу equals(), могут быть распределены по разным ячейкам хэш-таблицы, что может привести к неправильной работе коллекций.
Контракт hashCode
Для реализации хэш-функции в спецификации языка определены следующие правила:
- вызов метода hashCode один и более раз над одним и тем же объектом должен возвращать одно и то же хэш-значение, при условии что поля объекта, участвующие в вычислении значения, не изменялись.
- вызов метода hashCode над двумя объектами должен всегда возвращать одно и то же число, если эти объекты равны (вызов метода equals для этих объектов возвращает true).
- вызов метода hashCode над двумя неравными между собой объектами должен возвращать разные хэш-значения. Хотя это требование и не является обязательным, следует учитывать, что его выполнение положительно повлияет на производительность работы хэш-таблиц.
Пример переопределения equals() и hashCode() Вот пример, как можно переопределить методы equals() и hashCode() в пользовательском классе:
public class Person {
private String name;
private int age;
// Конструктор, геттеры и сеттеры
@Override public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
@Override public int hashCode() {
return Objects.hash(name, age);
}
}
В этом примере метод equals() сравнивает объекты Person по их имени и возрасту. Метод hashCode() использует метод hash() из класса Objects, чтобы вычислить хэш-код на основе имени и возраста.
Переопределение методов equals() и hashCode() важно, когда вы используете пользовательские классы в коллекциях, чтобы гарантировать правильное сравнение и поиск объектов.
Если вам понравилось, буду признателен за подписку.