假设某个班级MyClass
有3个变量,a
,b
和c
。该类还重写了hashCode(),它使用Joshua Bloch的方法计算返回值。
假设上述情况,假设MyClass()
和new MyClass()
如果其哈希码匹配则完全相等是否正确?
出于示例的目的,假设两个对象都使用相同的参数进行初始化
答案 0 :(得分:5)
当然不是。
hashCode
需要为等效对象生成相同的值,但不同的对象可能会产生相同的值。因此,以下是正确的(但效率低下的)hashCode
实现:
public int hashCode()
{
return 42;
}
即使你知道使用了特定的散列方法,假设hashCode
是完美的也是一个坏主意:稍后,一些重构/子类可能会用其他东西替换hashCode
实现。如果您需要这个,请创建一个始终返回完美哈希码的perfectHashCode
方法,并将其用于实现hashCode
回答你的初始问题:不,即使Bloch的方法afaics也不会产生完美的hashCode,因为(因为包裹在MAXINT上)2个不同的路径最终可能会碰撞到相同的哈希码。
这很容易想象:假设您的对象包含2个整数。哈希码只有1个整数。因此,对于2个整数的每个组合,它永远不会产生不同的值。
答案 1 :(得分:0)
如果哈希码匹配,则永远不能假设两个对象相等。哈希码相等只意味着对象可能相等,并且必须调用equals
来确定。哈希码不同意味着对象肯定不相等(提供hashCode()
正确一致equals
)。
答案 2 :(得分:0)
其他答案是正确的,但这是另一种查看方式:hashCode
会返回int
。如果您的对象具有String
作为其唯一成员且该字符串包含超过4个字节的字符,那么您在String
中已经拥有的信息比使用{表示的更多信息{1}}。一旦你意识到这一点,很明显int
返回的值无法完全表示对象。
由于hashCode
返回的值不能完全表示对象,因此它显然不能用于确定对象在语义上是否相等。
如果两个对象的hashCode
相等,你可以做的一件事:你可以假设它们是相同对象的相当合理的机会。因此,例如, hashCode
首先根据哈希码找到一个哈希桶,然后查看它在那里找到的每个对象(使用HashMap
),找到一个语义上等同于你实际需要的对象。