覆盖HashCode,什么时候不这样做会有问题?

时间:2016-05-18 19:09:31

标签: java object hashcode equality

当覆盖equals运算符以比较字段的对象时,也会说你应该覆盖hashCode()。

是否两个对象具有所有相同的字段,但是hashCodes()不同?为什么有必要更新两者?

2 个答案:

答案 0 :(得分:2)

覆盖两者的主要问题是很多容器都假设两种方法都使用相同的策略。

典型的情况是HashMaps,如果你覆盖equals()/ hashCode()中的一个而不是两者(或者不一致地覆盖它们),它们可能不起作用,因为它们使用hashCode()来找到你的密钥应该存储的桶然后,然后使用equals()在该桶内搜索。所以最终可能会在错误的桶中搜索给定的密钥!顺便说一句,这就是为什么有时你在get()时找不到一个键,但可以通过遍历每个元素来找到它:迭代不使用hadhCode()。

这是一个类似的推理,为什么你应该永远有一个hashCode()在对象在HashSet / HashMap中时改变它的值:当你搜索你的对象时,hashCode( )可能已经改变并将你发送到一个不正确的桶。

答案 1 :(得分:1)

a.equals(b)表示map.put(a, c); map.get(b)应该产生c,其中mapMapab是关键,c是有价值的。特别是,HashMap可以非常快速地执行这些操作,但依赖于a.hashCode()b.hashCode()来正确执行这些操作。如果a.hashCode() != b.hashCode()那么它们将不会被识别为等号密钥,使用HashMap的程序将以非常令人沮丧和混乱的方式行为不端。你应该总是假设这是一种可能性,即使你现在不打算这样做。 不要在没有其他的情况下实现一个。它也不难做到:你的IDE可能会为你生成它(和equals)。其他数据结构如HashSet也使用它。