Чӣ тавр дуруст равшан кардани усули 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() за строга проверка.