Kontrakt equals & hashCode wynika w dużej mierze z tego jak działają HashSet i HashMap. I jakby nie patrzeć dotyczy on sytuacji, gdzie wykorzystywane będą kolekcje oparte o obliczanie hashCode (czego umówmy się, najczęściej ciężko uniknąć podczas pisania kodu 😉 ).
Kontrakt
- Ponowne wywoływanie metody dla obiektu hashCode powinno zwracać tę samą wartość (dla pojedynczego uruchomienia aplikacji i przy nie zmieniającym się stanie obiektu)
- Jeśli a.equals(b) to a.hashCode() == b.hashCode()
(jeśli metoda equals zwaraca true dla dwóch obiektów, to metoda hashCode też musi zwracać te same wartości dla obu obiektów) - Jeśli !a.equals(b) to a.hashCode() == b.hashCode() lub a.hashCode() != b.hashCode()
(jeśli metoda equals zwraca false, to metoda hashCode może ale nie musi zwracać tych samych wartości dla obu obiektów)
Kontrakt z drugiej strony
Czyli zacznijmy teraz od warunku opartego o hashCode:
- Jeśli a.hashCode() == b.hashCode() to a.equals(b) lub !a.equals(b)
- Jeśli a.hashCode() != b.hashCode() to a.equals(b) lub !a.equals(b) (chodź wygląda to dosyć wątpliwie, powinno działać 🙂 )
Wydajność
Niektóre rozwiązania, takie jak na przykład zwracanie przez metodę hashCode() tej samej wartości, może znacząco wpłynąć na wydajność. Mimo tego, że jest to możliwe, bardziej wydajnym rozwiązaniem będzie zwracanie innych wartości hashCode dla każdego obiektu.
Warto zajrzeć
1. Przykłady z https://damianradowiecki.pl/java/hashset-i-hashmap/#examples
2. Wydajność przy metodzie hashCode zwracającej cały czas tą samą wartość
