java HashMap碰撞

时间:2013-01-09 17:24:55

标签: java hashmap

我正在阅读有关hashmap如何工作的内容。我正在阅读 的 "What will happen if two different objects have same hashcode" 即可。

根据它,如果两个对象具有相同的哈希码,它们都将存储在LinkedList中,但据我所知,如果两个哈希码然后前一个哈希码将被新的哈希码覆盖(如果我错了,请纠正我)。 / p>

有人可以更多地了解hashmap如何在内部使用对象作为键,如果两个对象具有相同的哈希码以及如何使用get()获取这两个对象会发生什么?

4 个答案:

答案 0 :(得分:39)

不,第一个没有被覆盖只是因为第二个具有相同的hashCode

只有当它也相等时才会被覆盖(如equals所述)。如果没有,两个值都将保留在链表中。

获取密钥时,具有相同hashCode的所有节点将与提供的密钥进行比较,直到其中一个相等,然后将返回其值(使用equals方法)。

如果地图中没有关键字相同,您将获得null

如果许多对象具有相同的hashCode(或者更准确地说是与内部Entry[] table模数相同的hashCode),那么唯一的问题是链接列表将始终被读取,这会更慢(并且会失败)任何哈希表的目的)。这就是设计hashcode方法以确保生成的整数分布良好的原因。

答案 1 :(得分:6)

让我解释一下hashmap的工作原理。

put方法的工作:

HashMap 基于散列原理工作,我们有put()get()方法来存储和检索对象形式的HashMap。当我们将两个键和值传递给put()方法以存储在HashMap上时,它使用关键对象hashcode()方法来计算哈希码,并通过对该哈希码应用哈希来识别用于存储值对象的存储桶位置。检索它时使用密钥对象equals方法来找出与该密钥关联的正确密钥值对和返回值对象。 HashMap在发生冲突时使用链表,对象将存储在链表的下一个节点中。 HashMap还将key + value元组存储在链表的每个节点中

使用get方法:

当我们将Key和Value对象传递给Java HashMap上的put()方法时,HashMap实现调用Key对象上的hashCode方法,并将返回的hashcode应用到自己的哈希函数中,以找到存储Entry对象的存储桶位置,重点要提到的是,Java中的HashMap将key和value对象存储为存储桶中的Map.Entry。如果在存储桶中找到多个Entry对象,它将调用同一存储桶中每个节点的ke.equals方法。

答案 2 :(得分:4)

假设您遵循defining hashCode and equals的规则,您描述的方案不会导致数据丢失。最多,性能会随着时间的推移而降低。

答案 3 :(得分:2)

在Java hashmap中,他们可以使用多种方法来完成它。从黑色时代的旧的CS 201数据结构课程开始:

1)哈希映射中的每个桶都可以成为链接列表的头部,其中包含添加的具有相同哈希值的所有条目。添加时发生冲突意味着您将新条目添加到链接列表的末尾。搜索意味着您必须在任何链接列表中对所有链接列表进行线性检查。

2)如果发生碰撞并且商店在概念上是一个数组,您可以从该点开始迭代,直到找到一个空白点并在那里添加新条目。对于搜索,这意味着如果您发现哈希桶已被占用,那么您必须从该点线性地比较支持哈希映射的数组中的下一个空点。

在这两种情况下,如果存在多个具有相同哈希的条目,则性能会下降。在一般情况下,这意味着哈希函数(用于生成哈希代码)返回少量可能的值,性能将随着地图填满而降低。 Java HashMap利用了50年的研究经验,很好地适应了通用数据进入散列映射的一般情况。

注意@dystroy根据equals()方法对地图中不能有两个条目的规则发表评论。