Как правилно да презапишете метода equals в Java?
sobes.tech AI
Отговор от AI
// Пример за минимално коректно пренаписване на equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Задължителна анотация
public boolean equals(Object o) {
// 1. Проверка за тождество
if (this == o) return true;
// 2. Проверка за null и съвпадение на класовете
// Използваме getClass() за строга проверка
if (o == null || getClass() != o.getClass()) return false;
// 3. Привеждане към тип
MyClass myClass = (MyClass) o;
// 4. Сравнение на важните полета
return id == myClass.id &&
// Използваме Objects.equals за сравнение на обекти (учита null)
Objects.equals(name, myClass.name);
}
}
Правила за коректно пренаписване на equals (съгласно контракт Object.equals):
- Рефлексивност: За всяка ненулева стойност
x,x.equals(x)трябва да връщаtrue. - Симетричност: За всяка ненулева стойност
xиy,x.equals(y)еtrueако и само акоy.equals(x)еtrue. - Транзитивност: За всяка ненулева стойност
x,y,z, акоx.equals(y)иy.equals(z)саtrue, тоx.equals(z)трябва да еtrue. - Константност: Многократното извикване на
x.equals(y)трябва да връща същия резултат, ако данните, използвани за сравнение, не са се променили. - За всяка ненулева стойност
x,x.equals(null)трябва да връщаfalse.
Препоръчва се използването на Objects.equals(obj1, obj2) за безопасно сравнение на обекти, тъй като правилно обработва null.
Винаги пренаписвайте hashCode(), когато пренаписвате equals(), според общия контракт Object.hashCode: ако два обекта са равни според equals(), техните hashCode() трябва да са еднакви. Обратното не е задължително. Неспазването на това правило ще доведе до неправилна работа на колекции, базирани на хеш таблици, като HashMap, HashSet.
// Пример за съответстващ hashCode за MyClass
class MyClass {
private int id;
private String name;
// ... конструктор и equals както по-горе ...
@Override
public int hashCode() {
// Използване на Objects.hash за лесно изчисление на хеш
return Objects.hash(id, name);
}
}
Методите equals и hashCode могат да бъдат генерирани автоматично с IDE (IntelliJ IDEA, Eclipse), което е добра практика.
Използвайте instanceof вместо getClass() само ако класът е част от йерархията и искате обекти от подкласове и суперкласове да се считат за равни, ако имат същото състояние. В повечето случаи е по-добре да използвате getClass() за строга проверка.