czwartek, 3 marca 2011

Metoda hashCode w javie

Nudów ciąg dalszy, czyli kilka słów o metodzie hashCode(), która powinna być zawsze nadpisana, jeśli nadpisaliśmy metodą equals().

1. Kontrakt dla metody hashCode().

Metoda musi spełniać następujące warunki:
  • W czasie działania aplikacji metoda zawsze zwraca tą samą wartość int, dla tego samego obiektu.
  • Jeśli dwa obiekty równe wg. metody equals() to wartości zwracane przez hashCode() dla tych obiektów muszą być takie same.
  • Jeśli dwa obiekty nie są równe wg. metody equals() to wartości zwracane przez hashCode() dla tych obiektów nie muszą być takie same. Aczkolwiek zaleca się taką implementację hashCode(), żeby dla różnych obiektów zwracała różne wartości hash, co wpływa pozytywnie na szybkość operacji na hashowalnych kolekcjach.
Chyba największą trudnością przy implementacji hashCode jest wybór odpowiednich pól, na bazie których, będzie liczony hash. Jak ktoś lubi może stosować różne kombinację podczas obliczania hash'a (cała masa tego w necie), ale chyba lepiej i wygodniej skorzystać z gotowych rozwiązań (Commons, Guava):
@Override
    public int hashCode() {
        
        return new HashCodeBuilder().append(someField)
                                    .append(someField2)
                                    .toHashCode();
    }

3 komentarze:

  1. Caveat: jak wrzucisz obiekt po hashu a potem przestawisz pole wchodzące w skład, to robi się źle.

    OdpowiedzUsuń
  2. @ags No tak, właśnie dlatego ta wartość musi być stała. Całkiem niedawno zresztą zastanawiałem się nad tym w kontekście Hibernate, gdzie naturalnym (i ryzykownym) podejściem wydaje się być użycie ID: http://stackoverflow.com/q/5174233/277683

    OdpowiedzUsuń
  3. ags: a propos czego jest Twój komentarz? Mam wrażenie, że jakiś inny (wcześniejszy) komentarz gdzieś się zapodział?

    OdpowiedzUsuń