1

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

4

4 回答 4

9

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

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

Eric Lippert写的关于哈希码的文章很好- 从 .NET 的角度来看,这是公认的,但原理是相同的。

于 2012-06-28T09:22:53.493 回答
2

不,没有hashCode()碰撞只意味着对象可能是相同的,这绝不是保证。

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

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

于 2012-06-28T09:22:49.573 回答
0

如果您没有覆盖该hashCode()方法,那么您的所有对象都是不相等的。通过覆盖它,您可以提供比较的逻辑。记住,如果你重写 hashCode(),你肯定应该重写equals(). 编辑: 当然仍然可能发生冲突,但是如果您没有 override equal(),您的对象将通过引用进行比较(对象等于自身)。

于 2012-06-28T09:24:39.873 回答
0

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

但是,实际的规范Object.hashCode()并没有保证,也不应该在任何合理或编写良好的代码中用于此目的。

我建议使用 Apache 公共库中提供的 hashCode 和 equals 构建器,或者如果您真的不能使用免费的外部库,请查看它们以获得灵感。不过,使用的最佳方法完全取决于“相等”在您的应用程序域上下文中的实际含义。

于 2012-06-28T09:27:37.153 回答