Обходной путь, когда хеш-код пересекает целочисленную границу

У меня есть 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, Не требуется, чтобы разные объекты имели разные hashCodes.

hashCode() а также equals() также должен быть быстрым. Вы можете улучшить производительность equals() сравнивая поля, скорее всего, сначала разные и возвращаясь рано. Вы не можете сделать это с hashCode() потому что расчет должен включать все соответствующие поля. Если в вашем классе 450 полей, вы можете рассмотреть возможность кэширования результата hashCode() или, лучше, реорганизацию вашего класса в меньшие единицы.

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

Обходной путь должен использовать другой метод для вычисления хэш-кода. Например, вы могли бы xor хэш-коды ваших 450 полей (кстати: вау!), но, не зная больше о вашем объекте, трудно сказать, будет ли это хорошим подходом для вашего конкретного случая.

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

Другие вопросы по тегам