2012-04-20 14 views
6

mi o dwie listy obiektów, użytkowników i produktyJava 2 hash mieszań

użytkowników własnych produktów, a każdy z produktów jest związany do 1 użytkownik

ale typ produktu może być wiele i być w posiadaniu oddzielnych użytkowników

  • użytkowników Ed Rob
  • produkty: Coca Sprites (1) Krasnale (2), piwo
  • Ed koki Sprites (1) Rob Sprites (2) i pszczoła r

muszę wygenerować identyfikator dla każdego unikalny (użytkownik + produkt)

To chyba nie jest dobry pomysł, aby zrobić

user.hashCode() + product.hashCode() 

Co może być dobrym sposobem, aby kontynuować?

+0

powiązanymi: http://stackoverflow.com/questions/2587442/hash-code-for-a-group-of-three-fields – Thilo

+2

'(37 * (17 + user.hashCode) + product.hashCode()) '. Zaczerpnięte ze skutecznej Java. –

+3

Hashcode nie są unikalne. Obiekty równe zwracają ten sam kod skrótu, ale ten sam kod nie oznacza, że ​​obiekty są równe. Nie pomyl hashcode dla identyfikatora. –

Odpowiedz

7

Twoja hashCode nie jest taka zła, jeśli zarówno użytkownik, jak i produkt tworzą pseudolosowe kody hash. Jeśli boisz kolizji hash z powodu złej implementacji hashcode w obu user lub product, a następnie pomnożyć jeden z kodów źródło hash przez liczby pierwsze:

public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((product == null) ? 0 : product.hashCode()); 
    result = prime * result + ((user == null) ? 0 : user.hashCode()); 
    return result; 
} 

Eclipse buduje ten właśnie kod przy wyborze Źródło | Wygeneruj hashCode() i equals().

Jak wspomniano przez Thilo, można również po prostu użyć Arrays.hashCode(new Object[]{ user, product }); To połączenie zajmuje się wartościami użytkownika lub produktu, a także mnoży wynik przez 31 - tak samo jak kod odręczny. Jeśli używasz Google Guava, istnieje Objects.hashCode(Object...), który sprawia, że ​​twoje intencje są trochę bardziej przejrzyste i używają varargs, ale to również przekazuje tylko Arrays.hashCode.

+0

, więc używasz tej samej liczby pierwszej co mnożnik użytkownika i produktu, dlaczego nie bierzesz dwóch różnych? –

+1

@ ca11111 istnieje już wpis na stackoverflow, który odpowiada na to o wiele lepiej niż kiedykolwiek mogłem: http://stackoverflow.com/a/1147232/112964 –

1

Powszechnym rozwiązaniem jest pomnożenie pierwszego hasha z liczbą pierwszą, a następnie dodanie drugiego skrótu.

4

Możesz pozwolić Apache Commons HashCodeBuilder wykonać pracę za Ciebie.

Pozwala napisać coś podobnego

return new HashCodeBuilder(17, 37). 
    append(user). 
    append(product). 
    toHashCode();