В какой ситуации целесообразно переопределить хэш-код в java?
Когда вы переопределяете equals
, в основном. Это означает, что коллекции, основанные на хэше (например, , HashSet
), могут очень быстро найти набор кандидатов объектов, которые будут равны тому, который вы ищете (или пытаетесь добавить, или что-то еще). Если у вас большая коллекция, вы разделите ее на ведра с помощью хеш-кода. Когда вы пытаетесь что-то посмотреть, вы найдете хэш-код объекта, который вы передали, и ищите объекты с одним и тем же хэш-кодом в соответствующем ведре. Затем для каждого объекта с точным точным хеш-кодом вы вызываете equals
, чтобы узнать, действительно ли эти два объекта: .
Для получения дополнительной информации см. Wikipedia article on hash tables.
EDIT: Быстрое примечание по выбору хэш-кодов ...
Это всегда действует просто переопределить hashCode
и вернуть часть постоянной (то же самое для каждого вызова) независимо от содержания объекта. Однако в этот момент вы теряете все преимущества хеш-кода - в основном контейнер на основе хэша будет думать, что любой экземпляр вашего вашего типа может быть равен любому другому, поэтому поиск по нему будет состоять из вызовов O (N) до equals
.
На другом конце шкалы, если вы не реализуете hashCode
правильно и возвращаете другого значения для звонков на равные объекты (или два вызовов на тот же объект дважды), вы не сможете найти объект, когда вы его ищете - разные хеш-коды будут исключать равенство, поэтому equals
даже не будет вызван.
Тогда есть аспект изменчивостью - это вообще плохая идея для equals
и hashCode
использовать изменяемые аспекты объекта: если вы мутировать объект в хэш-изменяя способ после того, как вы вставили его в хэш основе коллекции, вы не сможете найти его снова, потому что хэш во время вставки больше не будет правильным.
@RohitJain: Я видел это, но на самом деле это не говорит о цели *. –
@JonSkeet. Да, это действительно не так. Но где-то в глубине какого-то ответа он упоминается в небольшом заявлении. Тем не менее это будет полезно для OP. :) –