Java中哈希码和等式方法之间的关系

2022-08-31 09:17:22

我在很多地方读到过,虽然Java中覆盖了方法,但也应该覆盖方法,否则就是“违反契约”。equalshashCode

但到目前为止,如果我只覆盖等于方法,而不是哈希代码方法,我还没有遇到任何问题。

合同是什么?为什么我在违反合同时没有遇到任何问题?在哪种情况下,如果我没有覆盖hashCode方法,我会遇到问题吗?


答案 1

您将遇到的问题是集合,其中元素的单一性是根据 和 计算的,例如 ..equals().hashCode()HashMap

顾名思义,它依赖于哈希表,而哈希桶是对象的 函数。.hashCode()

如果你有两个对象,但它们有不同的哈希代码,你就输了!.equals()

这里合约中重要的部分是:.equals()的对象必须具有相同的.hashCode()

这一切都记录javadoc for Object中。Joshua Bloch说你必须在 Effective Java 中做到这一点。说得够多了。


答案 2

根据该文档,hashCode的默认实现将返回一些因每个对象而异的整数

尽管合理实用,但由类 Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的,但 JavaTM 编程语言不需要这种实现
技术。

但是,有时您希望具有相同含义的不同对象的哈希代码相同。例如

Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode

如果在集合框架中使用哈希数据结构(如 HashTable、HashSet),则会出现此类问题。特别是对于像HashSet这样的集合,你最终会有重复的元素并违反Set合约。


推荐