java - 项目 9 : "Always override hashCode() when you override equals"

标签 java equals

关于下面提到的 3 份契约(Contract):

1) Whenever hashCode() is invoked on the same object more than once during an execution of an application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.

从这句话中,我了解到,在应用程序的单次执行中,如果在同一对象上使用 hashCode() 一次或多次,它应该返回相同的值。

2) If two objects are equal according to the equals(Object) method, then calling the hashCode() method on each of the two objects must produce the same integer result.

从这句话中,我了解到,要在子类中执行相等操作(在广泛范围内),至少有四种不同程度的相等。

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

(b) 浅层结构相等:如果两个对象的所有字段都 ==,则两个对象“相等”。 { 例如,两个“size”字段相等且“head”字段指向同一个 SListNodeSingleLinkedList。}

(c) 深度结构相等:如果两个对象的所有字段都“相等”,则两个对象“相等”。 {例如,两个 SingleLinkedList 表示相同的“项”序列(尽管 SListNodes 可能不同)。}

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

基于上述四种相等性,第二个合约仅有效:if(Say) equals() 方法根据两个对象之间的逻辑相等性返回真值,然后 hashCode() 方法必须在为每个新对象生成整数之前在计算中考虑逻辑相等性,而不是考虑新对象的内部地址。

但是我在理解第三份契约(Contract)时遇到了问题。

3) IT IS NOT REQUIRED that if two objects are unequal according to the equals(Object) method, then calling the hashCode() method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

在第二份契约(Contract)中,正如我们所说的,hashCode()方法应该相应地[例如:在生成整数之前考虑逻辑相等]实现,我觉得,这是不正确的 是说,如果两个对象根据 equals(Object) 不相等,那么 hashCode() 方法可能会产生与第三个合约中提到的相同的整数结果?根据第二个合约中的参数,hashCode()必须产生不同的整数结果。仅仅在 hashCode() 中写入 return 42 就违反了第二份契约(Contract)!

请帮我理解这一点!

最佳答案

hashCode() 不可能总是为不相等的对象返回不同的值。例如,有 2^64 个不同的 Long 值,但只有 2^32 个可能的 int 值。因此,LonghashCode() 方法必须有一些重复。在这种情况下,您必须努力确保您的 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.

但是这个程序也打印 true:

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

关于java - 项目 9 : "Always override hashCode() when you override equals",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27658488/

相关文章:

java - 如何使用 oracle.jdbc.driver.OracleLog?

Java HashSet 包含对象

java - 通过抽象来强制执行 hashCode 和 equals 是否有任何优势?

java - 有效的java : q on comparison ( equals versus == )

java - 没有类型转换的Java编译器如何在子类中调用正确的equals()函数?

java - 将信息从 servlet 发送回 Filter

java - 在 Java 接口(interface)中保留参数名称

java - 有没有办法使用 Spring Security 检查 PHP 创建的 bcrypt 哈希值?

java - 以 HTML 形式传递字符串数组并提交给 Java Spring Controller?

java - 如何拥有一个 "inconsistent with equals"的 TreeSet