Sobes.tech
Middle

Opowiedz o umowach metodów equals i hashCode w Java.

sobes.tech AI

Odpowiedź od AI

  • Refleksyjność: dla dowolnej niezerowej wartości referencyjnej x, x.equals(x) powinno zwracać true.

  • Symetria: dla dowolnych niezerowych wartości referencyjnych x i y, x.equals(y) powinno zwracać true wtedy i tylko wtedy, gdy y.equals(x) zwraca true.

  • Przechodniość: dla dowolnych niezerowych wartości referencyjnych x, y i z, jeśli x.equals(y) zwraca true i y.equals(z) zwraca true, to x.equals(z) również powinno zwracać true.

  • Spójność: dla dowolnych niezerowych wartości referencyjnych x i y, wielokrotne wywołania x.equals(y) powinny zwracać konsekwentnie true lub false, pod warunkiem, że żadna informacja używana w porównaniach equals obiektów nie uległa zmianie między wywołaniami.

  • Dla dowolnej niezerowej wartości referencyjnej x, x.equals(null) powinno zwracać false.

  • Jeśli dwa obiekty są równe zgodnie z metodą equals(Object), to wywołanie metody hashCode dla każdego z nich powinno zwracać tę samą wartość całkowitą.

  • Nie jest konieczne, aby jeśli dwa obiekty nie są równe zgodnie z metodą equals(java.lang.Object), wywołanie metody hashCode dla każdego z nich zwracało różne wartości całkowite. Jednak programista powinien rozumieć, że generowanie różnych kodów hash dla nierównych obiektów może poprawić wydajność tablic haszujących.

Ważne jest nadpisanie obu metod equals i hashCode, jeśli jedna z nich jest nadpisywana, aby zachować kontrakt. Użycie equals bez nadpisania hashCode może prowadzić do nieprawidłowego działania kolekcji opartych na haszowaniu (np. 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; // Refleksyjność
        if (o == null || getClass() != o.getClass()) return false; // Sprawdzenie null i typu
        Person person = (Person) o;
        return age == person.age &&
               Objects.equals(name, person.name); // Porównanie zawartości
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // Generacja hash na podstawie pól
    }
}