当HasMap的大小增加时,其索引会发生什么变化?

时间:2018-10-26 07:39:33

标签: java dictionary hash hashmap hashtable

我了解当我们声明如下地图时

Map <String, Integer> map = new HashMap ();

默认加载因子为0.75,其大小为16,当地图的存储桶超过12个元素的数量时,大小更改为32。

但是,hascode % n定义了使用put函数时地图选择将放置对象的存储桶的索引的方式,但是当地图大小超过负载系数时会发生什么呢? n不再具有相同的值,因此,如果在应用hascode % n时所得到的索引与以前不同,该如何找到先前设置的条目?

我的最后一个问题是:

增加大小后,存储桶的索引如何相同?

4 个答案:

答案 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。

For Further Exposure

进一步的过程说明

  

当哈希表中的元素数量达到   地图达到最大阈值。

     

通常,负载系数值为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