当覆盖equals运算符以比较字段的对象时,也会说你应该覆盖hashCode()。
是否两个对象具有所有相同的字段,但是hashCodes()不同?为什么有必要更新两者?
答案 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
,其中map
是Map
,a
和b
是关键,c
是有价值的。特别是,HashMap
可以非常快速地执行这些操作,但依赖于a.hashCode()
和b.hashCode()
来正确执行这些操作。如果a.hashCode() != b.hashCode()
那么它们将不会被识别为等号密钥,使用HashMap
的程序将以非常令人沮丧和混乱的方式行为不端。你应该总是假设这是一种可能性,即使你现在不打算这样做。 不要在没有其他的情况下实现一个。它也不难做到:你的IDE可能会为你生成它(和equals
)。其他数据结构如HashSet
也使用它。