请耐心等待,因为我试图引入一个与许多活动线程直接矛盾的新概念。
HashSet中插入对象的条件是什么?
查看源代码,它归零为:
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
完整代码在:HashSet.java
所以,这取决于
- 哈希码
- 等于()
- == 即如果它们是相同的对象。
现在,我们知道如果 obj1.equals(obj2) 返回 true,则两个对象的哈希码必须相同。基于这 3 个参数的相对值,我创建了下表:
看条件号。4. 尽管 equals() 返回 false,对象被添加到 HashSet。在所有其他情况下,当且仅当 equals() 返回 false 时才添加对象。因此,可以说(忽略条件号 4),是否将对象添加到 HashSet 的决定仅由 equals() 方法决定。当被问及为什么我们使用 hashCode() 时,标准的回答是它通过简单地比较整数来提高性能,因为短路运算符节省了 equals() 方法的执行。这个论点在许多线程中都有讨论,例如如果我们无论如何都要检查等于,为什么要检查哈希?
但是,我发现这个论点是不正确的。如果 equals() 返回 false 并且 == 返回 true,Hashcode 实际上会做出决定。这是极不可能的,因为相同的对象通常为 equals() 返回 true,直到有人明确(违反 equals() 协定)覆盖 equals 方法,以便它为相同的对象返回不同的值。尽管如此,它还是有可能的,并且 java 似乎在某些违约代码的情况下提供了风险管理。你拿!