Реализация `hashCode ()` для очень простых классов - PullRequest
9 голосов
/ 30 января 2009

У меня очень простой класс только с одним членом поля (например, строка). Можно ли реализовать hashCode(), чтобы просто вернуть fieldMember.hashCode()? Или я должен как-то манипулировать хеш-кодом поля? Кроме того, если я должен манипулировать этим, то почему?

Ответы [ 9 ]

12 голосов
/ 30 января 2009

Если fieldMember является довольно хорошим способом уникальной идентификации объекта, я бы сказал, да.

10 голосов
/ 30 января 2009

Джошуа Блох излагает, как правильно переопределить equals и hashCode в "Эффективной Java" Глава 3 .

4 голосов
/ 30 января 2009

Умножение, добавление или ксерокопирование не сделают его более уникальным. Математически, вы будете применять константные функции к одной переменной, что не увеличивает количество возможных значений переменной.

Этот вид техники полезен для объединения нескольких хеш-кодов и при этом сохраняет сравнительно небольшой риск столкновений; он не имеет никакого отношения к одному хеш-коду.

2 голосов
/ 30 января 2009

Да, это довольно стандартно. И если класс отражает строку базы данных, я просто возвращаю первичный ключ.

1 голос
/ 30 января 2009

Если переменная 'fieldMember' уже реализует функцию 'hashCode', то вы можете использовать ее непосредственно из родительского класса. Если переменная 'fieldMember' является экземпляром пользовательского класса, вы должны самостоятельно реализовать его правильно. Прочитайте java.lang.Object API документацию в качестве руководства для реализации 'hashCode'.

1 голос
/ 30 января 2009

Существует только два реальных требования для hashCode: одно, чтобы экземпляры equals имели одинаковые хеш-коды, и два, чтобы hashCode работала достаточно быстро. Первое требование является наиболее важным на практике; без этого вы могли бы положить что-то в коллекцию, но не найти ее там. Второе - просто проблема производительности.

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

0 голосов
/ 02 февраля 2009

Как уже упоминал кто-то, вы должны следовать советам в Эффективной Java. Если вы переопределяете метод hashCode (), вы также должны переопределить метод equals (). Кроме того, оба метода должны быть согласованы.

Для упрощения написания хороших методов equals () и hashCode () я использую EqualsBuilder и HashCodeBuilder из Apache Commons Lang

Вот примеры:

public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    User other = (User) o;
    return new EqualsBuilder()
            .append(this.getUniqueId(), other.getUniqueId())
            .isEquals();
}

public int hashCode() {
    return new HashCodeBuilder()
            .append(this.getUniqueId())
            .toHashCode();
}
0 голосов
/ 30 января 2009

Обычно, если вы не используете этот объект в качестве ключа для * HashMap или элемента в * HashSet, hashCode () не нужно переопределять.

0 голосов
/ 30 января 2009

Ya. Это хорошая практика программирования. Я обычно использую:

return var ^ 1;

...