我正在阅读有关hashmap如何工作的内容。我正在阅读 的 "What will happen if two different objects have same hashcode" 即可。
根据它,如果两个对象具有相同的哈希码,它们都将存储在LinkedList
中,但据我所知,如果两个哈希码然后前一个哈希码将被新的哈希码覆盖(如果我错了,请纠正我)。 / p>
有人可以更多地了解hashmap如何在内部使用对象作为键,如果两个对象具有相同的哈希码以及如何使用get()
获取这两个对象会发生什么?
答案 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()方法对地图中不能有两个条目的规则发表评论。