为什么具有相同数据的两个不同的HashSet具有相同的HashCode?

Tyd*_*dal 3 java hashcode hashset

我最近在 leetcode 上遇到了一个问题,我用嵌套哈希集解决了这个问题。如果您有兴趣,这就是问题:https ://leetcode.com/problems/group-anagrams/ 。

我的直觉是将每个单词的所有字母添加到一个哈希集中,然后将该哈希集放入另一个哈希集中。在每次迭代中,我都会检查哈希集是否已经存在,如果存在,则添加到现有的哈希集。

奇怪的是,这似乎有效。如果两个哈希集是不同的对象,为什么它们共享相同的哈希码?类似的东西if(set1.hashCode() == set2.hashCode()) doStuff()是有效的代码吗?

kaa*_*aan 6

这是预料之中的。HashSet扩展了AbstractSet。AbstractSet 中的 hashCode() 方法表示

\n
\n

返回该集合的哈希码值。集合的哈希码定义为集合中元素的哈希码之和,其中空元素的哈希码定义为零。这确保了 s1.equals(s2) 意味着对于任何两个集合 s1 和 s2 来说 s1.hashCode()==s2.hashCode(),正如 Object.hashCode 的一般契约所要求的。

\n

此实现迭代集合,对集合中的每个元素调用 hashCode 方法,并将结果相加。

\n
\n

这是来自 AbstractSet 的代码:

\n
public int hashCode() {\n    int h = 0;\n    Iterator<E> i = iterator();\n    while (i.hasNext()) {\n        E obj = i.next();\n        if (obj != null)\n            h += obj.hashCode();\n    }\n    return h;\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

如果两个哈希集是不同的对象,为什么它们共享相同的哈希码?

\n
\n

对于 HashSet,hashCode 是使用集合的内容计算的。由于它只是数字加法,因此加法顺序并不重要,\xe2\x80\x93 只需将它们全部相加即可。因此,有两个集合是有意义的,每个集合都包含等效的对象(因此应该具有匹配的 hashCode() 值),然后每个集合中的 hashCode 总和是相同的。

\n
\n

类似的东西if(set1.hashCode() == set2.hashCode()) doStuff()是有效的代码吗?

\n
\n

当然。

\n

编辑:比较两个集合是否相等的最佳方法是使用equals(). 对于 AbstractSet,调用set1.equals(set2)将导致对equals()集合内对象级别的单独调用(以及一些其他检查)。

\n