HashMap

1、HashMap为什么是无序的?

HashMap源码629行

if ((p = tab[i = (n - 1) & hash]) == null)

​ n:数组长度

​ hash:元素hash值 tips:Integer类型的hash值是它本身

​ tab:数组

​ i =(n - 1) & hash :如果n=16(HashMap默认值) 则 i 的取值范围为[0,15]

​ 所以说 如果当前hash=16 则i = 0;则p被放入 tab[0]的链表或红黑树节点中

2、HashMap中转成红黑树的触发条件?

​ HashMap源码639-650行

//遍历数组链表节点
for (int binCount = 0; ; ++binCount) {
    if ((e = p.next) == null) {
        p.next = newNode(hash, key, value, null);
        //触发treeifyBin方法 当binCount=7时,也就是说当前元素为第8个时进入该方法
        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
            treeifyBin(tab, hash);
        break;
    }
    if (e.hash == hash &&
        ((k = e.key) == key || (key != null && key.equals(k))))
        break;
    p = e;
}

当链表上有8个元素时进入treeifyBin方法

//treeifyBin方法中 如果数组的长度小于64时。则进扩容方法resize()
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
            resize();

总结:

​ 链表节点转树节点的触发条件是a&&b

​ a、数组表的长度大于64

​ b、链表上的节点 >= 8

3、HashMap数组怎么扩容?

先看扩容的条件:

​ 1、数组为空

//627-628
if ((tab = table) == null || (n = tab.length) == 0)
    n = (tab = resize()).length;

​ 2、链表节点>=8 && 数组小于64

//756-757
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
    resize();

​ 3、数组总元素 > 容量负载临界点

//661-662 
//size 总元素个数永远自增长
//threshold The next size value at which to resize (capacity * load factor).
if (++size > threshold)
    resize();

​ 第一次 临界点 = 数组长度 * 负载因子(0.75) = 16 * 0.75 = 12

​ 第二次 临界点 = 临界点 << 2= 容量负载因子*2

​ 第n次:当容量大于( MAXIMUM_CAPACITY = 1 << 30 = 2^30 )时:临界点的值为int最大值 2^31-1

​ 数组长度范围[16,2^31-1]

再看扩容后的节点安排

​ 步骤:

​ 1、循环数组

​ 2、判断当前下标是否有值(无值则跳过,以下说明是有值的情况)

​ 3、判断当前下标Node节点,的下一个Node节点是否有值

​ 无值则直接添加到数组内, 数组下标 = 当前hash值 & 最大容量-1

​ 有值则进入第4点

​ 4、判断是否为树

​ true:分裂当前树

​ 5、重新计算所有节点,放入数组中

​ 计算条件

//当前hash 与 旧容器进行 & 运算
if ((e.hash & oldCap) == 0) {}

​ 如果是0放入原来下标位置

​ 如果非0则放入j+ oldCap (当前遍历的下标 + 旧容器大小)

​ tips:709行置空 目前猜测目的是:1、释放索引方便垃圾回收器回收 2、方便分裂树时,减少遍历

oldTab[j] = null;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值