【发布时间】:2012-06-27 01:04:06
【问题描述】:
我的理解是两个不相等的对象可以有相同的哈希码。从 HashMap java 添加或检索时如何处理?
【问题讨论】:
-
顺便说一句:您可以轻松地创建许多具有相同哈希码的 Long 值来尝试此操作。
new Long(n * 0x100000001L)对于n >= 0的 hashCode 都为 0
标签: java hashmap equals hashcode
我的理解是两个不相等的对象可以有相同的哈希码。从 HashMap java 添加或检索时如何处理?
【问题讨论】:
new Long(n * 0x100000001L) 对于 n >= 0 的 hashCode 都为 0
标签: java hashmap equals hashcode
HashMap 正在研究散列和索引的概念。 内部 HashMap 将值存储在节点数组中。 每个节点都表现为 LinkedList。
链表的每个节点都有4个值:
int hashK keyV valueNode<K, V> nextHashMap 内部结构:
在 HashMap 中插入值时,会生成 Key 的第一个 hashcode,并根据某种算法计算索引。
所以我们的值将与下一个元素的哈希码、键、值和地址一起存储在特定的索引中。
从 HashMap 中检索值时,首先生成哈希码,然后生成索引(与插入时的方式相同)。在从索引中获取值时,首先它会检查哈希码,如果哈希码匹配,那么它只会使用 equals 方法从 Node 中检查键。 如果键匹配,那么只有它会返回值,否则它将检查具有相同哈希码的下一个节点。
【讨论】:
当两个不相等的对象具有相同的哈希值时,这会导致哈希表中的冲突,因为两个对象都希望位于同一个槽(有时称为存储桶)中。哈希算法必须解决此类冲突。回到我大学算法课程的褪色记忆中,我记得这样做的三种基本方法:
我认为 Java 哈希类使用第三种方法,但它们可能使用组合方法。但是,良好散列的关键是确保散列表具有足够大的容量并编写良好的散列函数。一个只有与其持有的对象一样多的桶的哈希表可能会发生冲突。通常你希望哈希表大约是它存储的对象数量的两倍。 Java 的 HashMap 会根据需要增长,但如果你愿意,你可以给它一个起始容量和负载因子。
哈希函数由程序员决定。您可以只为所有对象返回 0,但这意味着散列(存储和检索)将变为 O(n) 而不是 O(1) ...或者用通俗的话来说,它会很慢。
参考:http://www.coderanch.com/t/540275/java/java/objects-hashcode-HashMap-retrieve-objects
【讨论】:
在这种情况下,您可以使用 IdentityHashMap,其中具有相同哈希的不同对象根据其身份被视为不同。
【讨论】:
在 HashMap 中,键及其关联值存储在桶中的链表节点中,并且键在 hashmap 中本质上是使用 equals() 方法而不是通过哈希码进行比较。
hm.put("a","aValue"); // Suppose hashcode created for key "a" is 209
hm.put("b","bValue"); // Here hashcode created for key "b" is 209 as well.
a.equals(b) 返回true,bValue 将替换aValue 并返回bValue。a.equals(b)返回false,则会在桶列表中创建另一个节点,所以当你调用get("b")时你会得到bValue,因为a.equals(b)是false。【讨论】:
它们只会被添加到同一个存储桶中,equals() 将用于区分它们。
每个桶可以包含一个具有相同哈希码的对象列表。
理论上,您可以为给定类的任何对象返回与哈希码相同的整数,但这意味着您失去了哈希映射的所有性能优势,并且实际上会将对象存储在列表中。
【讨论】: