Java hashCode()方法是对象相等的可靠度量吗?

我目前正在比较两个相同类型的复杂对象,其中多个字段由自定义对象类型的数据结构组成。 假设没有任何自定义对象覆盖hashCode()方法,如果我比较对象中每个字段的哈希码,并且它们将变成相同,我是否对所比较的内容有100%的信心对象是一样的吗? 如果没有,假设我不能使用任何外部库,那么您建议使用哪种方法来比较两个对象。

绝对不。 您应该使用hashCode()作为第一遍 – 如果哈希码不同,您可以假设对象不相等。 如果哈希码相同,则应调用equals()以检查完全相等。

以这种方式思考:只有2 32个可能的哈希码。 例如, String类型有多少可能的不同对象? 远不止于此。 因此,至少两个不相等的字符串必须共享相同的哈希码。

Eric Lippert 很好地描述了哈希码 – 诚然从.NET的角度来看,但原则是相同的。

不,缺少hashCode()碰撞只意味着对象可能是相同的,它永远不是保证。

唯一的保证是,如果hashCode()值不同(并且hashCode() / equals()实现是正确的),那么对象将 equal

另外,如果您的自定义类型没有hashCode()实现,那么该值对于比较对象的内容 完全没用 ,因为它将是identityHashCode()

如果您没有覆盖hashCode()方法,则所有对象都是不相等的。 通过覆盖它,您可以提供比较的逻辑。 请记住,如果你重写hashCode(),你肯定应该重写equals()编辑:当然还有一个碰撞,但如果你没有覆盖equal() ,你的对象将通过引用进行比较(一个对象等于它自己)。

Object.hashCode()的通常JVM实现是以某种格式返回对象的内存地址,因此这在技术上可以用于您想要的(因为没有两个对象可以共享相同的地址)。

但是, Object.hashCode()的实际规范不会产生任何保证,也不应该在任何合理或写得很好的代码中用于此目的。

我建议使用Apache commons库中可用的hashCode和equals构建器,或者如果你真的不能使用免费的外部库,只需看看它们的灵感。 最好的使用方法完全取决于应用程序域上下文中“相等”的实际含义。