我目前正在比较两个相同类型的复杂对象,其中多个字段由自定义对象类型的数据结构组成。假设没有任何自定义对象覆盖hashCode()
方法,如果我比较对象中每个字段的哈希码,并且它们结果是相同的,那么我是否有100%的信心比较对象是一样的吗?如果没有,假设我不能使用任何外部库,那么您建议使用哪种方法来比较两个对象。
答案 0 :(得分:8)
绝对不是。您应该仅使用hashCode()
作为第一遍 - 如果哈希码不同,您可以假设对象不相等。如果哈希码相同,则应然后调用equals()
以检查完全相等。
以这种方式思考:只有2个 32 可能的哈希码。作为示例,类型String
有多少可能的不同对象?远不止于此。因此,至少两个不相等的字符串必须共享相同的哈希码。
Eric Lippert writes well about hash codes - 诚然从.NET的角度来看,但原则是一样的。
答案 1 :(得分:2)
不,缺少hashCode()
碰撞只意味着对象可以相同,而永远不会保证。
唯一的保证是,如果hashCode()
值不同(且hashCode()
/ equals()
实施正确),那么对象不将是equal
。
此外,如果您的自定义类型没有hashCode()
实现,那么该值完全无用用于比较对象的内容,因为它将是identityHashCode()
。
答案 2 :(得分:0)
如果您没有覆盖hashCode()
方法,则所有对象都不相等。通过覆盖它,您可以提供比较的逻辑。请记住,如果您覆盖hashCode(),您绝对应该覆盖equals()
。
修改强>
当然还有一个碰撞,但如果你没有覆盖equal()
,你的对象将通过引用进行比较(一个对象等于它自己)。
答案 3 :(得分:0)
Object.hashCode()
的通常JVM实现是以某种格式返回对象的内存地址,因此技术上可以用于你想要的东西(因为没有两个对象可以共享同一个地址)。
然而,Object.hashCode()
的实际规范并不构成任何保证,不应在任何明智或写得很好的代码中用于此目的。
我建议使用Apache commons库中可用的hashCode和equals构建器,或者如果你真的不能使用免费的外部库,只需看看它们的灵感。最好的使用方法完全取决于应用程序域上下文中“相等”的实际含义。