Cum se suprascrie corect metoda equals în Java?
sobes.tech AI
Răspuns de la AI
// Exemplu de redefinire minim corectă a metodei equals
class MyClass {
private int id;
private String name;
public MyClass(int id, String name) {
this.id = id;
this.name = name;
}
@Override // Adnotare obligatorie
public boolean equals(Object o) {
// 1. Verificare de identitate
if (this == o) return true;
// 2. Verificare pentru null și potrivire de clase
// Folosim getClass() pentru o verificare strictă
if (o == null || getClass() != o.getClass()) return false;
// 3. Cast
MyClass myClass = (MyClass) o;
// 4. Compararea câmpurilor semnificative
return id == myClass.id &&
// Folosim Objects.equals pentru compararea obiectelor (gestionează null)
Objects.equals(name, myClass.name);
}
}
Reguli pentru o redefinire corectă a equals (conform contractului Object.equals):
- Reflxivitate: Pentru orice valoare nenulă
x,x.equals(x)trebuie să returnezetrue. - Simetrie: Pentru orice
xșiynenuli,x.equals(y)trebuie să returnezetruedacă și numai dacăy.equals(x)returneazătrue. - Transitivitate: Pentru orice
x,y, șiznenuli, dacăx.equals(y)șiy.equals(z)sunttrue, atuncix.equals(z)trebuie să fietrue. - Consistență: Pentru orice
xșiynenuli, multiple apeluri lax.equals(y)trebuie să returneze în mod consecventtruesaufalse, atâta timp cât informațiile utilizate pentru comparație nu s-au schimbat. - Pentru orice
xnenul,x.equals(null)trebuie să returnezefalse.
Se recomandă utilizarea Objects.equals(obj1, obj2) pentru compararea sigură a obiectelor, deoarece gestionează corect null.
Întotdeauna redefinește hashCode() atunci când redefinești equals(), în conformitate cu contractul general al Object.hashCode: dacă două obiecte sunt egale conform equals(), hash-urile lor, returnate de hashCode(), trebuie să fie identice. Condiția inversă nu este obligatorie. Nerespectarea acestei reguli poate duce la funcționarea incorectă a colecțiilor bazate pe tabele hash (de exemplu, HashMap, HashSet).
// Exemplu de hashCode corespunzător pentru MyClass
class MyClass {
private int id;
private String name;
// ... constructor și equals ca mai sus ...
@Override
public int hashCode() {
// Utilizarea Objects.hash pentru calcularea hash-ului
return Objects.hash(id, name);
}
}
Poți genera automat metodele equals și hashCode folosind IDE-uri (IntelliJ IDEA, Eclipse), ceea ce reprezintă o bună practică.
Folosește instanceof în loc de getClass() doar dacă clasa face parte dintr-o ierarhie de moștenire și vrei ca obiectele superclase și subclase să fie considerate egale dacă au același stadiu. În majoritatea cazurilor, este preferabil să folosești getClass() pentru o verificare strictă.