2010-08-05 1 views
1

Я бегу в вопрос о равных и Hashcode контрактов: здесьравно и хэш-код

Дано:

class SortOf { 
    String name; 
    int bal; 
    String code; 
    short rate; 
    public int hashCode() { 
    return (code.length() * bal); 
    } 
    public boolean equals(Object o) { 
    // insert code here 
    } 
} 

Какой из следующих будет выполнять Equals() и хэш-код() контракты для этого класс? (Выберите все подходящие варианты.)

Правильный ответ C:

return ((SortOf)o).code.length() * ((SortOf)o).bal == this.code.length() * 
    this.bal; 

D:

return ((SortOf)o).code.length() * ((SortOf)o).bal * ((SortOf)o).rate == 
    this.code.length() * this.bal * this.rate; 

У меня есть вопрос о последнем выбора D, скажем, если два объекта

A: code.length = 10, bal = 10, rate = 100

B: code.length = 1 0, bal = 100, rate = 10

Затем, используя метод equals() в D, мы получаем A.equals(B), оценивая true справа? Но тогда они получают другой hashCode, потому что у них разные балансы? Разве что я где-то неправильно понял эту концепцию? Может ли кто-нибудь прояснить это для меня?

ответ

4

Вы правы - D был бы неуместным из-за этого.

В целом, hashCode и equals должны в основном учитывать те же поля, таким же образом. Это очень странная реализация equals, с которой, конечно же, вы обычно должны проверять равенство между каждым из задействованных полей. В некоторых случаях поля могут быть взаимосвязаны таким образом, чтобы это позволяло умножать и т. Д., Но я бы не ожидал, что это связано с длиной строки ...

Важным моментом, который часто смущает людей, является то, что он действителен для неравных объектов, имеющих одинаковый хеш-код; это тот случай, который вы выделили (равные объекты, имеющие разные хэш-коды), что неприемлемо.

0

Вы должны проверить, по крайней мере, все поля, используемые .hashCode(), поэтому объекты, которые равны, имеют одинаковый хеш. Но вы можете проверить больше полей на равных, и это вполне нормально, чтобы иметь разные объекты с одинаковым хешем. Кажется, что вы делаете SCJP 1.6? Эта тема хорошо освещена в книге SCJP 1.6 от Кэтрин Сьерра и Берт Бейтс.

Примечание: вот почему его законная реализовать полезную .equals() при возвращении на постоянное значение из .hashCode()

+0

Спасибо за помощь, я думаю, что у меня есть. Да, я использую эту книгу для изучения scjp, и я получил этот вопрос из симулятора экзамена. – y62wang

+0

Вы также можете прочитать эту тему в «Эффективном Java Second Edition» Джоша Блоха. Очень приятно объяснил! –

+0

<3 эффективных java ... – atamanroman

0

Это все о выполнение контракта (насколько этот вопрос затронут). Разная реализация (hasCode и equal) имеет разные ограничения и свои преимущества - поэтому разработчик должен проверить это.

, но затем они получают разные хэш-коды, потому что они имеют другой баланс?
Ровно! Но вот почему вы должны выбрать вариант C. Вопрос хочет проверить ваше понимание на , выполнив концепцию контракта, а не то, что hascode будет лучше для сценария.

Более уточнение:
Что вам нужно проверить, всегда: Ваша hashCode() реализация должна использовать одни и те же переменные экземпляра, используемые в equals() методе.

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

-1

В общем, вы должны всегда переопределять его, если вы переопределяете другую в классе. Если вы этого не сделаете, вы можете столкнуться с проблемами, когда этот класс используется в hashmaps/hashtables и т. Д.

+2

Вопрос не в том: «Должен ли я переопределить?», Речь шла об их реализации. Это отвечает на другой вопрос. –

+0

Извините, новичок – user3774979