HashMap基本的实现流程之扩容

本文接上篇:
《HashMap最基本的实现流程(源码角度)》

前言

上篇主要说了HashMap的put操作实现的主流程,分析了源码中某些关键步骤之所以那样写的原因;对于一些分支流程没有过多展开,这里就填一下扩容的坑(注意:本文还是基于jdk1.7)

扩容

这里先把涉及到扩容的地方的源码贴一下:

    void addEntry(int hash, K key, V value, int bucketIndex) {
   
        if ((size >= threshold) && (null != table[bucketIndex])) {
   
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }

        createEntry(hash, key, value, bucketIndex);
    }

如上图代码,这是HashMap添加元素的函数,上一篇中我们假设还没到扩容的条件,先走了下面的主流程,这里我们就来看一下分支流程——扩容;

1. 扩容的条件

即什么时候会触发扩容?回答这个问题时这里可能会有一个误区(不怕笑话,我之前就是按误区这么想的),就是当 数组存的元素个数大于阈值的时候 会触发扩容,并且回答时脑海中浮现的比例图是下图:
在这里插入图片描述
其实直到我真的去看了HashMap的源码我才意识到我的错误。上一篇我一开始也特别强调了下size的含义;其实触发扩容的条件应该是这样的:当哈希表中存的元素个数(size:数组+链表存的元素)超过了阈值(threshold)时。

这样就对了嘛?对了一半,看源码中判断的条件,是一个且运算,即后面还有半句,这就表示并不是size>threshold时就会扩容,什么时候size>threshold但还不扩容呢?——当要存的下一个元素的索引并没有冲突时。如下图,假设现在的参数情况如下:

capacity=4(2^2)
loadfactor=0.75
threshold=capacity*loadFactor=3
size=3(满足扩容第一个条件)

存储情况如下图:
在这里插入图片描述
这时要添加的元素的索引被计算出来是3(或者2),因为此时2或者3的位置都没有元素(即tab

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值