Sobes.tech
Middle

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ă returneze true.
  • Simetrie: Pentru orice x și y nenuli, x.equals(y) trebuie să returneze true dacă și numai dacă y.equals(x) returnează true.
  • Transitivitate: Pentru orice x, y, și z nenuli, dacă x.equals(y) și y.equals(z) sunt true, atunci x.equals(z) trebuie să fie true.
  • Consistență: Pentru orice x și y nenuli, multiple apeluri la x.equals(y) trebuie să returneze în mod consecvent true sau false, atâta timp cât informațiile utilizate pentru comparație nu s-au schimbat.
  • Pentru orice x nenul, x.equals(null) trebuie să returneze false.

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ă.