Ako správne prepísať metódu equals v Jave?
sobes.tech AI
Odpoveď od AI
// Príklad minimálne správneho prepísania equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Povinná anotácia
public boolean equals(Object o) {
// 1. Kontrola identity
if (this == o) return true;
// 2. Kontrola na null a zhodu tried
// Používame getClass() pre prísnu kontrolu
if (o == null || getClass() != o.getClass()) return false;
// 3. Typová konverzia
MyClass myClass = (MyClass) o;
// 4. Porovnanie dôležitých polí
return id == myClass.id &&
// Používame Objects.equals pre porovnanie objektov (zohľadňuje null)
Objects.equals(name, myClass.name);
}
}
Pravidlá pre správne prepísanie equals (podľa kontraktu Object.equals):
- Reflexivita: Pre akékoľvek nenullové
x,x.equals(x)musí vracaťtrue. - Symetria: Pre nenullové
xay,x.equals(y)jetrueak a len aky.equals(x)jetrue. - Tranzitivita: Pre nenullové
x,y,z, akx.equals(y)ay.equals(z)sútrue, takx.equals(z)jetrue. - Konzistentnosť: Opakované volanie
x.equals(y)by malo dávať stále rovnaký výsledok, pokiaľ sa nezmenia dáta na základe ktorých sa porovnáva. - Pre nenullové
x,x.equals(null)musí vracaťfalse.
Odporúča sa používať Objects.equals(obj1, obj2) pre bezpečné porovnanie objektov, pretože správne zaobchádza s null.
Vždy prepisujte hashCode(), ak prepisujete equals(), podľa všeobecného kontraktu Object.hashCode: ak sú dva objekty rovné podľa equals(), ich hashCode() musia byť rovnaké. Opak nie je povinný. Nedodržanie tohto pravidla spôsobí nesprávnu funkciu kolekcií založených na hash tabuľkách, ako sú HashMap, HashSet.
// Príklad zodpovedajúcej implementácie hashCode pre MyClass
class MyClass {
private int id;
private String name;
// ... konštruktor a equals ako vyššie ...
@Override
public int hashCode() {
// Použitie Objects.hash pre jednoduché výpočty hash
return Objects.hash(id, name);
}
}
Metódy equals a hashCode je možné generovať automaticky v IDE (IntelliJ IDEA, Eclipse), čo je dobrá prax.
Používajte instanceof namiesto getClass() iba ak je trieda súčasťou dedičnosti a chcete, aby objekty nadtriedy a podtriedy boli považované za rovné, ak majú rovnaký stav. Vo väčšine prípadov je vhodnejšie použiť getClass() pre prísnu kontrolu.