Ответ
Контракт между equals() и hashCode(), определенный в Java, гласит:
- Если два объекта равны согласно методу
equals(Object o), то вызовhashCode()для каждого из них должен возвращать одно и то же целочисленное значение. - Обратное не обязательно: разные объекты (по
equals) могут иметь одинаковый хеш-код (коллизия).
Почему это критично для QA-инженера? Нарушение этого контракта приводит к некорректной работе hash-коллекций (HashMap, HashSet, HashTable). Объект, добавленный в HashSet, может в нем не найтись, что вызывает трудноуловимые баги.
Пример корректной реализации для класса User:
import java.util.Objects;
public class User {
private final Long id;
private final String name;
// Конструктор, геттеры...
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id) && Objects.equals(name, user.name);
}
@Override
public int hashCode() {
// Используем вспомогательный метод Objects.hash() для согласованного вычисления
return Objects.hash(id, name);
}
}
На практике: При написании или ревью кода, где классы используются как ключи в HashMap или элементы в HashSet, я всегда проверяю, что оба метода переопределены согласованно.