2014-11-26 3 views
1

Я следующий класс Java:Объединение хэша строки и хэша Long

public class Person{ 
    String name; //a unique name 
    Long DoB;  //a unique time 
    . 
    . 
    . 
    @Override 
    public int hashCode(){ 
    return name.hashCode() + DoB.hashCode(); 
    } 

} 

Является ли мой метод хэш-код правильный (т.е. будет ли возвращать уникальное число всех комбинаций

У меня есть чувство. Я что-то здесь отсутствует

+0

'equals' override. Вы можете захотеть умножить длинный на что-то нечетное, например, 31. –

+0

нет, этого не будет. 'hash (a) + hash (b)! = hash (a + b)'. в то время как не совсем легко сделать, кто-то, возможно, мог бы найти совершенно другую строку SINGLE, которая хэшируется с тем же значением, что и ваш комбинированный хэш (a) + hash (b). –

+0

@DaveNewton У меня тоже равное переопределение. следует добавить его к вопросу? – nafas

ответ

1

Вы также можете использовать что-то более свободно и более NPE-Пуленепробиваемый как Google Guava:

@Override 
public int hashCode(){ 
    return Objects.hashCode(name, DoB); 
} 

@Override 
public boolean equals(Object o) { 
    if (this == o) { 
     return true; 
    } 
    if (o == null || o.getClass() != Person.class) { 
     return false; 
    } 
    final Person that = (Person) o; 
    return Objects.equal(name, that.name) && Objects.equal(DoB, that.DoB); 
} 

Edit:

IntelliJ IDEA и Eclipse, может генерировать более эффективный hashCode() и equals() ,

+0

** + 1 ** Я не показывал свой метод equals, его почти такой же, как за исключением того, что я не проверяю, является ли o нулевым. – nafas

3

Вы могли бы позволить java.util.Arrays сделать это для вас:.

return Arrays.hashCode(new Object[]{ name, DoB }); 
1

Помимо для очевидного, который вы можете реализовать метод equals, а также ...

  • Суммируя два хэш-кодов имеет очень небольшой риск перелива int
  • Сама сумма кажется немного слабой методологии для предоставления уникальных хеш-кодов. Вместо этого я попытался бы поразрядным манипуляциям и использовать семя.
0

обычно хэш строится так:

@Override 
    public int hashCode(){ 
    return name.hashCode()^DoB.hashCode(); 
    } 

но важно помнить при выполнении метода Hashcode является использование его. использование метода hashcode заключается в том, чтобы поместить другой объект в разные ведра в хэш-таблицу или другую коллекцию, используя hashcode. как таковой, бессильно иметь метод, который дает разные ответы на разные объекты в малом времени выполнения, но не обязательно должен быть различным для каждого элемента, хотя это лучше.

Этот хэш используется другим кодом при хранении или перемещении экземпляра - значения предназначены для быть равномерно распределены по различным входов для того, чтобы использовать в кластеризации. Это свойство важно производительность хэш-таблиц и других структур данных, которые хранят объекты в группы («ведра») на основе их вычисленного значения хэш-

и

генподряда для переопределяется реализация этого метода равна , что они ведут себя так, как это соответствует одному и тому же объекту equals() метод: чтобы данный объект должен последовательно сообщать о том же хэше значение (если оно не изменено, так что новая версия больше не рассмотреть ed "равно" старому), и что два объекта, равных() , равны, должны сообщать о том же значении хэш-функции.

0

См. Эффективную Java-версию Блоха # 9.

Но вы должны начать с начального значения (так что последующие нулевые значения значительны) и объединить поля, которые применяются к результату, вместе с множителем, чтобы порядок был значительным (так что аналогичные классы будут иметь очень разные хэши .)

Кроме того, вам придется обрабатывать такие вещи, как длинные поля и струны, несколько иначе. например, для длинных позиций:

(int) (field^(field>>>32)) 

Таким образом, это означает что-то вроде:

@Override public int hashCode() { 
    int result = 17; 
    result += name.hashCode() == null ? 0 : name.hashCode(); 
    result = 31 * result + (int) (DoB^(DoB >>> 32)); 
    return result; 
} 

31 немного магии, но нечетные простые числа могут сделать его проще для компилятора, чтобы оптимизировать математику перекладывать-вычитание. (Или вы можете сделать смену вычитания самостоятельно, но почему бы не позволить компилятору сделать это.)

0

Реализация вашего хеш-кода выполнена правильно и правильно. Было бы лучше, если бы вы выполнили любые предложения, сделанные другими людьми, но это удовлетворяет контракту на hashCode, и столкновения не особенно вероятны, хотя их можно было бы сделать менее вероятными.

Смежные вопросы