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