Sobes.tech
Middle

Hoe overschrijf je de methode equals correct in Java?

sobes.tech AI

Antwoord van AI

// Voorbeeld van minimale correcte herdefinitie van equals
class MyClass {
    private int id;
    private String name;

    public MyClass(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override // Verplichte annotatie
    public boolean equals(Object o) {
        // 1. Identiteitscontrole
        if (this == o) return true;
        // 2. null- en klassecontrole
        // Gebruik getClass() voor strikte controle
        if (o == null || getClass() != o.getClass()) return false;
        // 3. Casten
        MyClass myClass = (MyClass) o;
        // 4. Vergelijking van belangrijke velden
        return id == myClass.id &&
               // Gebruik Objects.equals voor objectvergelijking (houdt null in acht)
               Objects.equals(name, myClass.name);
    }
}

Regels voor correcte herdefinitie van equals (volgens het contract van Object.equals):

  • Reflectiviteit: Voor elke niet-nul waarde x, moet x.equals(x) true retourneren.
  • Symmetrie: Voor alle niet-nul waarden x en y, moet x.equals(y) true zijn als en alleen als y.equals(x) true is.
  • Transitiviteit: Voor niet-nul x, y, en z, als x.equals(y) en y.equals(z) true zijn, dan moet x.equals(z) ook true zijn.
  • Consistentie: Meerdere aanroepen van x.equals(y) moeten consistent hetzelfde resultaat geven, zolang de informatie die wordt gebruikt voor de vergelijking niet verandert.
  • Voor elke niet-nul waarde x, moet x.equals(null) false retourneren.

Het wordt aanbevolen om Objects.equals(obj1, obj2) te gebruiken voor veilige objectvergelijking, omdat het null-waarden correct behandelt.

Altijd hashCode() overschrijven wanneer equals() wordt overschreven, in overeenstemming met het algemene contract van Object.hashCode: als twee objecten gelijk zijn volgens equals(), moeten hun hashcodes gelijk zijn. De omgekeerde implicatie is niet vereist. Het niet naleven hiervan kan leiden tot incorrect gedrag van hash-gebaseerde collecties (bijvoorbeeld HashMap, HashSet).

// Voorbeeld van een bijpassende hashCode voor MyClass
class MyClass {
    private int id;
    private String name;

    // ... constructor en equals zoals hierboven ...

    @Override
    public int hashCode() {
        // Gebruik Objects.hash voor eenvoudige hash-berekening
        return Objects.hash(id, name);
    }
}

Je kunt de methoden equals en hashCode automatisch genereren met IDE's (IntelliJ IDEA, Eclipse), wat een goede praktijk is.

Gebruik instanceof in plaats van getClass() alleen als de klasse deel uitmaakt van een erfhiërarchie en je wilt dat objecten van de superklasse en subklasse als gelijk worden beschouwd als ze dezelfde toestand hebben. In de meeste gevallen is het beter om getClass() te gebruiken voor strikte controle.