Переопределение hashCode () - это достаточно хорошо? - PullRequest
7 голосов
/ 14 декабря 2010

Для класса, поля которого являются исключительно примитивными, например:

class Foo
{
    int a;
    String b;
    boolean c;
    long d;

    boolean equals(Object o)
    {
        if (this == o) return true;
        if (!(o instanceof Foo)) return false;
        Foo other = (Foo) o;
        return a == other.a && b.equals(other.b) && c == other.c && d = other.d;
    }
}

Это достаточно "хороший" способ написать hashCode()?

boolean hashCode()
{
    return (b + a + c + d).hashCode();
}

То есть я создаю String из тех же полей, которые использует equals(), а затем просто использую String#hashCode().

Редактировать: Я обновил свой вопрос, добавив поле long. Как обрабатывать long в hashCode()? Просто дайте ему переполниться int?

Ответы [ 2 ]

7 голосов
/ 14 декабря 2010

Ваш хеш-код удовлетворяет свойству, что если два объекта равны, то их хеш-коды должны быть равны. Таким образом, это «достаточно хорошо». Однако довольно просто создать коллизии в хеш-кодах, которые ухудшат производительность структур данных на основе хеш-функции.

Я бы реализовал это немного по-другому, хотя:

public int hashCode() {
    return a * 13 + b.hashCode() * 23 + (c? 31: 7);
}

Вам следует ознакомиться с документацией для метода hashCode() из Object. В нем изложены вещи, которым должен удовлетворять хэш-код.

0 голосов
/ 14 декабря 2010

Это полностью зависит от того, как будут выглядеть ваши данные. В большинстве случаев это был бы хороший подход. Если у вас часто будет b, заканчивающийся цифрой, то вы получите несколько дублирующих кодов для неравных объектов, как показывает ответ JacobM. Если вы заранее знаете, что b почти никогда не будет иметь числового значения в конце, то это разумный алгоритм хеширования.

...