Kolekcje Java – hashCode() i equals() – Jak przesłonić metody equals() i hashcode() w Javie?

Opublikowany: 2018-08-08
hashCode i equals kolekcji Java

equals() i hashCode() w Javie to dwie podstawowe metody, które są zadeklarowane w klasie Object i części lub rdzeniu biblioteki Javy.

Jeśli masz jakiekolwiek z poniższych obaw w Javie, to jesteś we właściwym miejscu.

  • Praktyki Java -> Implementacja równa się
  • override – Zastępowanie równości i hashCode w Javie
  • Jak nadpisać metodę equals() w java
  • Jak nadpisać metodę hashCode() w java
  • Jak nadpisać metodę równości i hashCode w Javie?
  • Jak i dlaczego zastąpić metodę równości w Javie?
  • Dlaczego zawsze zastępować hashcode(), jeśli zastępowanie równa się()?

Rzućmy okiem na prosty przykład, aby zrozumieć najpierw Reference Equality i Logical Equality . Operator równości (==) porównuje referencje (adresy w pamięci) dwóch ciągów jako dwie różne liczby — jest to znane jako Reference equality .

Logical equality porównuje dane obiektów zamiast wartości referencji.

Wyjście:

hashCode i równorzędne są ściśle powiązane :

  • jeśli zastąpisz równa się, musisz zastąpić hashCode .
  • hashCode musi generować równe wartości dla równych obiektów.
  • equals i hashCode muszą zależeć od tego same set of significant fields . W obu tych metodach musisz użyć tego samego zestawu pól. Nie musisz używać wszystkich pól. Na przykład pole obliczeniowe, które zależy od innych, powinno najprawdopodobniej zostać pominięte w equals i hashCode .

Podczas implementacji equals pola są porównywane w różny sposób, w zależności od ich typu:

  • pola obiektów, w tym kolekcje : use equals
  • wyliczenia z bezpiecznym typem : użyj równych lub == (w tym przypadku sprowadzają się do tego samego)
  • prawdopodobnie puste pola obiektów : użyj zarówno == , jak i równa się
  • pola tablicy : użyj Arrays.equals
  • pola pierwotne inne niż float lub double : użyj ==
  • float : przekonwertuj na int za pomocą Float.floatToIntBits , a następnie użyj ==
  • double : przekonwertuj na long używając Double.doubleToLongBits , a następnie użyj ==

Implementacja hashCode :

  • jeśli klasa nadpisuje wartość równa , musi nadpisać hashCode
  • gdy oba są nadpisane, equals i hashCode muszą używać tego samego zestawu pól
  • jeśli dwa obiekty są równe, to ich wartości hashCode również muszą być równe
  • jeśli obiekt jest niezmienny, hashCode jest kandydatem do buforowania i leniwej inicjalizacji

Jest to popularne błędne przekonanie, że hashCode zapewnia unikalny identyfikator obiektu. To nie.

Zgodnie z ogólnym kontraktem metoda equals() w Javie musi być zwrotna, symetryczna, przechodnia, spójna, a każde odwołanie niezerowe musi zwracać wartość fałsz. Innymi słowy, dla dowolnych wartości a, b i c, następujące testy muszą zawsze zaliczyć:

Aby uzyskać najlepsze praktyki, wykonaj poniższe czynności, aby zaimplementować metodę equals():

  • Użyj tego == that, aby sprawdzić równość referencji
  • Użyj instanceof , aby przetestować poprawny typ argumentu
  • Przekształć argument na właściwy typ
  • Porównaj znaczące pola pod kątem równości

Oto kompletny przykład.

CrunchifyImplementEqualsHashCode.java

Dane wyjściowe konsoli Eclipse: