Сочетание хэша строки и хэша длинного

1

У меня есть следующий класс java:

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

}

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

У меня такое чувство, что я что-то пропустил.

  • 0
    equals переопределение. Возможно, вы захотите умножить длинный на что-то странное, например, 31.
  • 0
    нет не будет hash(a) + hash(b) != hash(a+b) . хотя это не совсем легко сделать, кто-то может найти совершенно другую строку SINGLE, которая хэширует то же значение, что и объединенный хэш (a) + hash (b).
Показать ещё 4 комментария
Теги:

6 ответов

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);
}

Редактировать:

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

  • 0
    +1 Я не показывал свой метод equals, он почти такой же, как у вас, за исключением того, что я не проверяю, имеет ли o ноль
3

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

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

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

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

См. Bloch Эффективная 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, и столкновения не особенно вероятны, хотя их можно было бы сделать менее вероятными.

0

обычно хэш-код создается так:

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

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

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

а также

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню