2013-09-24 3 views
1

Я очень благодарен, если вы сможете устранить мои сомнения Предположим, у меня есть класс A и B A имеет ссылку B, говорят b1 и b2. как в классе А переопределяет равный метод что-то вроде b1.equal (other.b1) и b2.equal (other.b2)сомнения в реализации hashcode в java

и переопределить метод хэш-то вроде

int result = 1; 
result = 17* result + ((b1== null) ? 0 : b1.hashCode()); 
result = 17* result + ((b2== null) ? 0 : b2.hashCode()); 
return result; 

это мой Правильно ли используется метод hashcode? , а также если я звоню b1.hashcode(), тогда он также вызовет метод hashcode класса B? если да, то это обязательно для переопределения равных и hashcode в классе B?

Заранее спасибо.

+0

Выглядит хорошо для меня. –

+1

Этот вопрос выглядит не по теме, поскольку он касается качества кода и принадлежит [codereview.se]. –

ответ

1

Это выглядит правильно. Да, вы должны переопределить hashCode и равные методы класса B.

+0

Переопределите методы equals и hashCode в классе B, если и только если реализации, которые они наследуют, не подходят. Если B расширяет объект напрямую, это означает, что если два отдельных экземпляра B равны. –

+0

@PatriciaShanahan Мы можем видеть, что OP ожидает переопределить значения в B (см. 'B1.equal (other.b1)'). Если он это делает, то также необходимо переопределить hashCode, чтобы сохранить правильную семантику, поэтому я думаю, что мы согласны. –

+0

Да, если B нужно объявить метод equals, а не наследовать от его суперкласса, очень важно переопределить hashCode. –

2

только требование hashCode() в Java - это согласованность. Это означает, что два идентичных экземпляра Aдолжны вернуть тот же хэш-код. Если ваш код делает это, то вы технически хороши. Это означает, что технически действует функция hashCode(), которая является просто return 1. Очевидно, что это плохая реализация, потому что она имеет 100% -ную скорость столкновения. Поэтому, чтобы сделать хорошую функцию hashCode, вы также должны минимизировать скорость столкновения.

С учетом этого ваш код выглядит хорошо.

+2

+1, но небольшая настройка: единственным требованием для функциональной правильности является то, что равные объекты имеют один и тот же хэш-код. Производительность - это реальное требование, даже если оно не оформлено в API. Всегда возвращать '0' из hashCode правильно так же, как всегда сортировка с сортировкой пузырьков; функционально это, но в большинстве случаев на практике это невозможно. – yshavit

+0

Да, вы правы, производительность всегда важна. –

1

Выглядит хорошо, хотя это может быть упрощена:

int result = ((b1== null) ? 0 : b1.hashCode()); 
result = 17* result + ((b2== null) ? 0 : b2.hashCode()); 
return result; 
+0

Вряд ли любое упрощение там. –

+1

One line нет. Вы могли бы вывести еще одну строку, просто выполнив «return 17 * result + ((b2 == null)? 0: b2.hashCode());', но опять же это только для вертикальной недвижимости. Никакой реальной оптимизации не происходит здесь. –

+0

Могу сказать, что есть по крайней мере причина смешать хэш-коды с мультипликатором.В принципе нет точки A) начинать с константы 1, B) умножать указанную константу на 17, что вы могли бы просто сделать, выбирая другую константу и C) добавляя константу к следующему значению в первую очередь. В основном: это не упрощает многое, неважно, насколько это важно, но если человек написал это вручную, он был излишне подробным. – James

Смежные вопросы