第9项:"覆盖等于"时始终覆盖hashCode()

ove*_*nge 0 java equals

关于下面提到的3份合同:

1)每当hashCode()在执行应用程序期间多次在同一对象上调用时,该hashCode方法必须始终返回相同的整数,前提是不修改在对象的等比较中使用的信息.从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致.

从这个陈述中,我理解,在单个执行应用程序时,如果hashCode()在同一个对象上使用一次或多次,它应该返回相同的值.

2)如果两个对象根据equals(Object)方法相等,则hashCode()在两个对象中的每一个上调用方法必须产生相同的整数结果.

从这个陈述中,我理解,要在子类中执行相等操作(在宽范围内),至少有四种不同的相等程度.

(a)引用相等(==),比较两个引用类型对象的内部地址.

(b)浅层结构平等:如果所有字段均为==,则两个对象为"等于".{例如,两个SingleLinkedList"大小"字段相等且"头部"字段指向相同的字段SListNode.}

(c)深层结构平等:如果所有字段都是"等于",则两个对象"等于".{例如,两个SingleLinkedList代表相同序列的"项目"(尽管SListNodes可能不同).}

(d)逻辑平等.{两个例子:(a)如果两个"Set"对象包含相同的元素,则它们是"equals",即使基础列表以不同的顺序存储元素.(b)分数1/3和2/6是"等于",即使它们的分子和分母都不同.}

基于以上四类相等,第二个契约只能保持良好:如果(Say)equals()方法基于两个对象之间的logical_equality返回真值,那么hashCode()方法还必须在计算中考虑逻辑_equality,然后为每个新对象生成整数,而不是考虑内部地址一个新的对象.

但我在理解这第三份合同时遇到了问题.

3)根据equals(Object)方法,如果两个对象不相等,则不需要hashCode()在两个对象中的每一个上调用方法必须产生不同的整数结果.但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能.

在第二个合同中,正如我们所说的那样hashCode()方法应该相应[例如:考虑生成整数之前的logical_equality]实现,我觉得,如果两个对象根据then 方法不相等可能会产生相同的整数结果,这是不正确的如第三份合同中所述?根据第二个合同中的参数,必须产生不同的整数结果.一个只是写在被打破第二份合同!equals(Object)hashCode()hashCode() return 42hashCode()

请帮我理解这一点!

Pau*_*ton 5

hashCode()总是为不相等的对象返回不同的值是不可能的.例如,有2 ^ 64个不同的Long值,但只有2 ^ 32个可能的int值.因此,hashCode()方法Long必须有一些重复.在这种情况下,您必须尽力确保您的hashCode()方法尽可能均匀地分配值,并且不太可能为您最有可能在实践中使用的实例生成重复.

第二个条件只是说两个equal()实例必须返回相同的hashCode()值,所以这个程序必须打印为true:

Long a = Long.MIN_VALUE;
Long b = Long.MIN_VALUE;
System.out.println(a.hashCode() == b.hashCode()); // a.equals(b), so must print true.
Run Code Online (Sandbox Code Playgroud)

但是这个程序也打印为true:

Long c = 0L;
Long d = 4294967297L;
System.out.println(c.hashCode() == d.hashCode()); // prints true even though !c.equals(d)
Run Code Online (Sandbox Code Playgroud)