【发布时间】:2014-12-26 14:43:52
【问题描述】:
关于以下3份合同:
1) 每当在应用程序执行期间对同一个对象多次调用
hashCode()时,hashCode方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要在应用程序的一次执行与同一应用程序的另一次执行之间保持一致。
从这句话中,我了解到,在应用程序的单次执行中,如果 hashCode() 在同一个对象上使用一次或多次,它应该返回相同的值。
2) 如果两个对象根据
equals(Object)方法相等,那么对两个对象中的每一个调用hashCode()方法必须产生相同的整数结果。
从这个陈述中,我了解到,要在您的子类中执行相等操作(在广泛的范围内),至少有四种不同程度的相等。
(a)引用相等(==),比较两个引用类型对象的内部地址。
(b) 浅结构相等:如果两个对象的所有字段都是 ==,则它们是“相等的”。
{ 例如,两个SingleLinkedList,其“大小”字段相等,其“头”字段指向相同的SListNode。}
(c) 深层结构相等:如果两个对象的所有字段都“相等”,则它们是“相等”的。
{例如,两个 SingleLinkedList 代表相同的“项目”序列(尽管 SListNodes 可能不同)。}
(d) 逻辑相等。 {两个例子: (a) 如果两个“Set”对象包含相同的元素,则它们是“相等的”,即使底层列表以不同的顺序存储元素。 (b) 分数 1/3 和 2/6 是“等于”的,即使它们的分子和分母都不同。}
基于以上四类相等,第二个合约只成立: if(Say) equals() 方法根据两个对象之间的逻辑相等返回真值 then hashCode() 方法必须也考虑在为每个新对象生成整数之前计算中的logical_equality,而不是考虑新对象的内部地址。
但是我在理解第三份合同时遇到了问题。
3) 如果两个对象根据
equals(Object)方法不相等,则对这两个对象中的每一个调用hashCode()方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
在第二份合同中,正如我们所说,hashCode() 方法应该被相应地实施[例如:在生成整数之前考虑logical_equality],我觉得,如果这样说不是真的根据equals(Object),两个对象不相等,那么hashCode() 方法可能会产生与第三个合同中提到的相同的整数结果?根据第二份合同中的论点,hashCode() 必须 产生不同的整数结果。一个只是在hashCode() 中写return 42 的人违反了第二份合同!
请帮助我理解这一点!
【问题讨论】:
-
hashCode返回什么值类型? -
hashCode() 返回整数
-
你的感受并不重要。该文档指出,对于不同的值,哈希码可以相同,这很重要。这是一个与其他任何设计决策一样的设计决策 - 到目前为止,我还没有读到任何论据为什么它“必须”产生不同的值。
-
@JeroenVannevel 是的,文档说:
hashcodes can be the same for distinct values,那么这意味着我们不应该在任何上下文中链接这两种方法,但我们也说,You must override hashCode() in every class that overrides equals(),因为你想从@987654344 确保什么@ 方法,无论何时覆盖equals(),你都会覆盖hashCode()? -
如果您有一组对象并且您覆盖了一个方法而不是另一个,它可能会在错误的存储桶中搜索您的对象。或者它可能会在正确的存储桶中搜索,但它可能无法识别它。更多信息:stackoverflow.com/questions/27581/…