我了解当我们声明如下地图时
:Map <String, Integer> map = new HashMap ();
默认加载因子为0.75,其大小为16,当地图的存储桶超过12个元素的数量时,大小更改为32。
但是,hascode % n
定义了使用put函数时地图选择将放置对象的存储桶的索引的方式,但是当地图大小超过负载系数时会发生什么呢? n不再具有相同的值,因此,如果在应用hascode % n
时所得到的索引与以前不同,该如何找到先前设置的条目?
我的最后一个问题是:
增加大小后,存储桶的索引如何相同?
答案 0 :(得分:3)
我认为您要问的是“增加大小后,存储区的索引如何相同?”
好吧,简单的答案就是不能。 HashMap
必须在扩展时对所有元素进行重新哈希处理。
请参阅以下方法:
/**
* Transfers all entries from current table to newTable.
*/
void transfer(Entry[] newTable, boolean rehash) {
,由resize
调用。上面写着的JavaDoc
刷新,将此地图的内容放入具有更大尺寸的新数组中 容量。按键数量自动调用此方法 在这张地图中达到了阈值。
强调地雷
另请参阅:
答案 1 :(得分:2)
HashMap
的默认初始容量为16,负载系数为0.75f(即当前地图尺寸的75%)。负载因子表示应将HashMap
的容量提高一倍。
例如的容量和负载系数乘积为16 * 0.75 = 12
。这表示在将第12个键值对存储到HashMap
后,其容量变为32。
进一步的过程说明
当哈希表中的元素数量达到 地图达到最大阈值。
通常,负载系数值为0.75,默认初始容量为 值是16。一旦元素数量达到或超过0.75次 容量,然后重新映射。在这种情况下 元素数为12,则发生重新哈希处理。 (0.75 * 16 = 12)
重新进行哈希处理时,会产生新的哈希函数甚至是相同的哈希 可以使用功能,但是存在值的存储桶 可能会改变。基本上在进行重新哈希处理时,存储桶数 大约增加一倍,因此新索引的值 必须进行更改。
重新哈希时,每个存储区的链表在 订购。发生这种情况是因为HashMap不会在以下位置附加新元素 相反,尾部将新元素附加在头部。所以什么时候 进行重新哈希处理时,它将读取每个元素并将其插入到新元素中 桶在头,然后继续添加旧的下一个元素 地图位于新地图的顶部,导致链接列表颠倒。
如果有多个线程处理同一个哈希映射,则可能 导致无限循环。
上面详细说明了无限循环的发生方式 案例可以在这里找到:
Read this Article for more unserstanding
如果必须使用键对插入地图的元素进行排序,则 可以使用TreeMap。但是如果HashMap的顺序为 键无关紧要。
答案 2 :(得分:-1)
内部数据 结构被重建。从文档中:https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html:
当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表将被重新哈希(即,内部数据结构将被重建),因此哈希表的数量大约是哈希表的两倍。桶。
答案 3 :(得分:-1)
Hashmaps不保留顺序。请考虑改用LinkedHashMaps。