Sobes.tech
Middle

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é x a y, x.equals(y) je true ak a len ak y.equals(x) je true.
  • Tranzitivita: Pre nenullové x, y, z, ak x.equals(y) a y.equals(z)true, tak x.equals(z) je true.
  • 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.