我对Hashing和Rehashing有些困惑。以下是我的理解,如果我错了,请纠正我。
根据图片,bucket实际上是Entry类的数组,它以链表的形式存储元素。每个新的键值对,其键具有相同的条目数组桶的哈希码,将被存储为存储该哈希码元素的桶中的条目对象。如果密钥具有条目阵列桶中当前不存在的新哈希码,则将添加具有相应哈希码的新桶。
现在的问题是,实际重新发生时会发生什么?
案例1:假设我有一个入口数组,其中包含哈希码1,2 3的桶,当时Entry Array Bucket达到12就可以添加新元素,但是只要一个新元素的哈希码为13(假设我正在添加一系列哈希码1和2等系列元素,一个新的入口桶地图/数组(请说明哪一个)将被创建,新容量将是32,现在Entry数组可以保持不同32桶。
案例2:桶数量,HashMap 16的默认容量意味着它可以存储16个元素,无论如何都可以在单桶中存储。因为加载因子.75,一旦添加了第13个元素,就会创建一个新的桶数组,其中包含32个,即现在所有链接列表中的总条目节点可以是32个。
我认为案例2是正确的。请使用Re Hashing过程,如果使用此图表,则更好。
答案 0 :(得分:5)
Rehashing根据当前存储在HashMap
中的条目数增加可用存储桶的数量。
当HashMap
实现确定应增加存储区数量以保持预期的O(1)
查找和插入性能时,就会发生这种情况。
关于.75默认加载因子以及在添加第13个条目时它将如何重新出现HashMap
,你是对的。
然而,default capacity of HashMap 16 means it can store 16 element in it
不正确。任何桶都可以存储多个条目。但是,为了保持所需的性能,每个桶的平均条目数应该很小。这就是我们有加载因子的原因,也是我们应该使用适当的hashCode()
的原因,这些HTML
会尽可能均匀地分散密钥。
答案 1 :(得分:1)
Rehashing是重新计算已存储条目(键值对)的哈希码的过程,在达到加载因子阈值时将它们移动到另一个更大的哈希映射。
当map中的项目数超过当时的加载因子限制时,hashmap将其容量加倍,并且重新计算已存储元素的哈希码,以便在新桶中均匀分配键值对。
为什么需要重组?
在容量增加一倍之后,如何处理桶中已存在的键值对?
如果我们保持现有的键值对,那么将容量加倍可能无济于事, 因为只有当项目均匀分布在所有桶中时才能实现O(1)复杂性。
因此,对于每个现有键值对,再次使用增加的hashmap容量作为参数计算哈希码,这导致将项目放在相同的存储桶或不同的存储桶中。
重新发布以在新长度散列映射中分配项目,以便获取和放置操作时间复杂度保持为O(1)。
注意:强>
Hashmap在插入数据并从hashmap获取数据时保持O(1)的复杂性,但对于第13个键值对,put请求将不再是O(1),因为只要map将实现第13个元素进来了,就是75%的地图被填满了。
它将首先加倍桶(数组)容量,然后它将用于Rehash。 Rehashing需要再次重新计算已经放置的12个键值对的哈希码,并将它们放在需要时间的新索引上。
你应该阅读它可能会有所帮助
http://javabypatel.blogspot.co.il/2015/10/what-is-load-factor-and-rehashing-in-hashmap.html