Обходной путь, когда хеш-код пересекает целочисленную границу
У меня есть POJO
Имея ~450 полей, и я пытаюсь сравнить экземпляры этого POJO с помощью hascode. Я создал переопределенный hashCode()
метод с затмением. Во многих случаях сгенерированный хэш-код пересекает целочисленную границу. В результате становится все труднее проводить сравнение. Какой обходной путь?
hashCode()
Метод заключается в следующем:
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((stringOne == null) ? 0 : stringOne.hashCode());
result = prime * result + intOne;
result = prime * result + Arrays.hashCode(someArray);
result = prime * result + ((stringTwo == null) ? 0 : stringTwo.hashCode());
result = prime * result + intTwo;
result = prime * result + intThree;
result = prime * result + ((stringThree == null) ? 0 : stringThree.hashCode());
result = prime * result + ((stringFour == null) ? 0 : stringFour.hashCode());
result = prime * result + ((stringFive == null) ? 0 : stringFive.hashCode());
result = prime * result + ((objectOne == null) ? 0 : objectOne.hashCode());
result = prime * result + ((objectTwo == null) ? 0 : objectTwo.hashCode());
return result;
}
2 ответа
Целочисленное переполнение является нормальной частью hashCode()
расчеты. Это не проблема.
Например, hashCode()
из String
часто отрицательный.
System.out.println("The hashCode() of this String is negative".hashCode());
Если hashCode()
расчет может переполниться, очевидно, это может означать, что неравный Object
может иметь то же самое hashCode
, но это может произойти без переполнения. Например, оба эти печати true
,
System.out.println("Aa".hashCode() == "BB".hashCode());
System.out.println(new HashSet<>(Arrays.asList(1, 2)).hashCode() == Collections.singleton(3).hashCode());
Единственное требование - одинаковые объекты должны иметь одинаковые hashCode
, Не требуется, чтобы разные объекты имели разные hashCode
s.
hashCode()
а также equals()
также должен быть быстрым. Вы можете улучшить производительность equals()
сравнивая поля, скорее всего, сначала разные и возвращаясь рано. Вы не можете сделать это с hashCode()
потому что расчет должен включать все соответствующие поля. Если в вашем классе 450 полей, вы можете рассмотреть возможность кэширования результата hashCode()
или, лучше, реорганизацию вашего класса в меньшие единицы.
Другая вещь, которую стоит рассмотреть, - нужно ли вообще переопределять эти методы. Это абсолютно необходимо, если объекты собираются использовать в качестве ключей в контейнере на основе хеша, например HashMap
,
Обходной путь должен использовать другой метод для вычисления хэш-кода. Например, вы могли бы xor
хэш-коды ваших 450 полей (кстати: вау!), но, не зная больше о вашем объекте, трудно сказать, будет ли это хорошим подходом для вашего конкретного случая.
В идеале, поскольку хеш-коды используются для хеширования, объекты, которые не равны, также должны с высокой вероятностью создавать разные хеш-коды.