2012-04-20 2 views
6

Я имею два списка объектов, пользователей и продуктыJava хэш 2 хэшей

пользователей собственные продукты, и каждый из продуктов связан с 1 пользователя

но тип продукта может быть несколько и принадлежать отдельных пользователи

  • пользователи: Ed, Rob
  • продукты: Кока, Sprites (1), спрайты (2), Пиво
  • Ed имеет Кок и спрайты (1), Робы спрайты (2) и пчелка г

Мне нужно создать идентификатор для каждого уникального (пользователь + продукт)

Это, вероятно, не очень хорошая идея, чтобы сделать

user.hashCode() + product.hashCode() 

Что может быть хорошим способом, чтобы продолжить?

+0

Связанный: http://stackoverflow.com/questions/2587442/hash-code-for-a-group-of-three-fields – Thilo

+2

'(37 * (17 + user.hashCode) + product.hashCode()). Взято из эффективной Java. –

+3

Хаскоды не уникальны. Равные объекты возвращают один и тот же хэш-код, но тот же хэш-код не означает, что объекты равны. Не допускайте ошибки hashcode для ID. –

ответ

7

Ваш hashCode не так уж плох, если пользователь и продукт создают псевдослучайные хэш-коды. Если вы боитесь хэш столкновений из-за плохие реализации Hashcode в любом user или product, а затем умножить один из исходного хэша-кодов с помощью простого числа:

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, строит этот самый код при выборе Источника | Сгенерируйте hashCode() и equals().

Как упоминалось в Thilo, вы также можете просто использовать Arrays.hashCode(new Object[]{ user, product }); Этот вызов позаботится о значениях null для пользователя или продукта, а также умножает результат на 31 - то же, что и ручной код. Если вы используете Google Guava, есть Objects.hashCode(Object...), который делает ваше намерение немного понятным и использует varargs, но он также делегирует только Arrays.hashCode.

+0

, так что вы используете то же самое простое число, как множитель пользователя и продукта, почему бы не взять 2 разных? –

+1

@ ca11111 уже есть сообщение в stackoverflow, которое отвечает на это намного лучше, чем я когда-либо мог: http://stackoverflow.com/a/1147232/112964 –

1

Общим решением является умножение первого хеша с простым числом, а затем добавление второго хэша.

4

Вы можете позволить Apache Commons HashCodeBuilder выполнить работу за вас.

Это позволяет писать что-то вроде

return new HashCodeBuilder(17, 37). 
    append(user). 
    append(product). 
    toHashCode(); 
Смежные вопросы