JDK1.8 HashMap 扩容机制

本文详细介绍了JDK1.8中HashMap的扩容过程,包括何时触发扩容、扩容的规则以及具体步骤。在扩容时,HashMap会创建一个新的两倍大小的Node数组,并对原数组中的元素进行rehash,确保元素分散在新数组的不同位置,避免冲突。在rehash过程中,通过key的hash值进行计算,保证了原有元素分布的均匀性。
摘要由CSDN通过智能技术生成

先看一下原函数的注释

    /**
     * Initializes or doubles table size.  If null, allocates in
     * accord with initial capacity target held in field threshold.
     * Otherwise, because we are using power-of-two expansion, the
     * elements from each bin must either stay at same index, or move
     * with a power of two offset in the new table.
     *
     * @return the table
     */
使用场景

Initializes or doubles table size.

resize 规律

原来某个坑位中的元素,要么还留在原来的位置,要么移动 a power of two 个位置。实际上是移动原来数组长度个位置。


整体流程

  1. newTab = new 一个二倍原长度的 Node 数组,threshold 变成两倍;
  2. 将 table (Map中存放元素的容器)指向 newTab;
  3. 依次遍历原来 Node 数组的每个坑位,将坑中的元素进行 rehash。

一个 table length 从 8 到 16 的 扩容例子

当然实际数组初始长度最小为 16, 不存在从 8 到 16 的扩容,只是为了好画图。

假设元素的 hash(key) = key

Node 节点中存储的 hash 其实就是 key 的 hash 值

亦即:(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)

Node 节点定义:

static class Node<K,V> implements Map.Entry<K,V> {
   
        final int hash;
        final K key;
        V value;
        Node<K,V> next;
        
        // otherThings
}
0. 初始状态

一个长度为 8 的数组,loadfactor = 0.75,threshold = 6.

    /**
     * The next size value at which to resize (capacity * load factor).
     *
     * @serial
     */
    int threshold;

在这里插入图片描述

1. 建立新table

resize() 函数会在两种情况下被调用:

  1. HashMap new 出来后还没有 put 元素进去,没有真正分配存储空间被初始化,调用 resize() 函数进行初始化;
  2. 原 table 中的元素个数达到了 capacity * loadFactor 这个上限,需要扩容。此时调用 resize(),new 一个两倍长度的新 Node 数组,进行rehash,并将容器指针(table)指向新数组。
    final Node
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值