Sobes.tech
Middle

Pověz o kontraktech metod equals a hashCode v Javě.

sobes.tech AI

Odpověď od AI

  • Reflexivita: pro jakoukoli nenulovou referenční hodnotu x by x.equals(x) mělo vracet true.

  • Symetrie: pro jakékoli nenulové referenční hodnoty x a y by x.equals(y) mělo vracet true právě tehdy, když y.equals(x) vrací true.

  • Transitivita: pro jakékoli nenulové referenční hodnoty x, y a z, pokud x.equals(y) vrací true a y.equals(z) vrací true, pak by x.equals(z) mělo také vracet true.

  • Konzistence: pro jakékoli nenulové referenční hodnoty x a y, by opakované volání x.equals(y) mělo konzistentně vracet true nebo false, za předpokladu, že žádné informace používané v porovnání equals objektů se mezi voláními nezmění.

  • Pro jakoukoli nenulovou referenční hodnotu x by x.equals(null) mělo vracet false.

  • Pokud jsou dva objekty rovny podle metody equals(Object), pak by volání metody hashCode pro každý z těchto dvou objektů mělo vracet stejnou celou hodnotu.

  • Není nutné, aby pokud dva objekty nejsou rovny podle metody equals(java.lang.Object), volání hashCode pro každý z nich vracelo různé celé hodnoty. Nicméně programátor by měl pochopit, že generování odlišných hash kódů pro nerovné objekty může zlepšit výkon hash tabulek.

Je důležité přepsat obě metody equals a hashCode, pokud je jedna z nich přepsána, aby se zachoval kontrakt. Použití equals bez přepsání hashCode může vést k nesprávnému chování kolekcí založených na hashování (například HashMap, HashSet).

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // Reflexivita
        if (o == null || getClass() != o.getClass()) return false; // Kontrola null a typu
        Person person = (Person) o;
        return age == person.age &&
               Objects.equals(name, person.name); // Porovnání obsahu
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // Generování hash na základě polí
    }
}