🤔 Расскажи про Hash Code & Equals ContractКогда вы переопределяете методы
equals() и
hashCode(), важно соблюдать контракт, иначе объект может вести себя некорректно в коллекциях (
HashMap,
HashSet и др.).
🚩
Контракт `equals()` Метод
equals() определяет, когда два объекта равны.
Рефлексивность –
x.equals(x) всегда
true.
Симметричность –
x.equals(y) == y.equals(x).
Транзитивность – если
x.equals(y) и
y.equals(z), то
x.equals(z).
Согласованность – многократные вызовы
x.equals(y) дают один и тот же результат.
Сравнение с
null всегда
false –
x.equals(null) == false.
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = 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 && name.equals(person.name); // Сравнение полей
}
}🚩
Контракт `hashCode()` Метод
hashCode() возвращает числовой хеш-код объекта. Он должен соответствовать
equals()!
Если
x.equals(y) == true, то
x.hashCode() == y.hashCode().
Если
x.hashCode() != y.hashCode(), то
x.equals(y) == false (но обратное не всегда верно).
Хеш-код должен оставаться неизменным, если объект не изменяется.
@Override
public int hashCode() {
return Objects.hash(name, age);
}
🚩
Почему контракт `equals()` и `hashCode()` важен? В коллекциях, таких как
HashSet,
HashMap,
HashTable, объекты хранятся по хеш-коду.
Что будет, если
equals() переопределён, но
hashCode() – нет?
Set<Person> people = new HashSet<>();
people.add(new Person("Иван", 25));
people.add(new Person("Иван", 25)); // Ожидаем, что не добавится
System.out.println(people.size()); // ❌ Будет 2, а не 1, если `hashCode()` отсутствует!
Правильный вариант (
equals() +
hashCode())
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = 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 && name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}Ставь 👍 и забирай 📚 Базу знаний