当我们首次调用 HashMap
的 put()
方法存数据时,如果发现 table
为 null
,则会调用 resize()
去初始化 table
,具体逻辑在 putVal()
方法中。
在 resize()
方法中,调整了最终 threshold
值,以及完成了 table
的初始化。
因为 resize()
还糅合了动态扩容的逻辑,所以我将初始化 table
的逻辑用注释标记出来了。其中 xxxCap
和 xxxThr
分别对应了 table
的容量
和动态扩容
的阈值
,所以存在旧
和新
两组数据。
当我们指定了初始容量,且 table
未被初始化时,oldThr
就不为 0
,则会走到代码 ①
的逻辑。在其中将 newCap
赋值为 oldThr
,也就是新创建的 table
会是我们构造的 HashMap
时指定的容量值。
之后会进入代码 ②
的逻辑,其中就通过装载因子(loadFactor
)调整了新的阈值(newThr
),当然这里也做了一些限制需要让 newThr
在一个合法的范围内。
在代码 ③
中,将使用 loadFactor
调整后的阈值,重新保存到 threshold
中。并通过 newCap
创建新的数组,将其指定到 table
上,完成 table
的初始化(代码 ④
)。
到这里也就清楚了,虽然我们在初始化时,传递进来的 initialCapacity
虽然经过 tableSizeFor()
方法调整后,直接赋值给 threshold
,但是它实际是 table
的尺寸,并且最终会通过 loadFactor
重新调整 threshold
。
那么回到之前的问题就有答案了,虽然 HashMap
初始容量指定为 1000
,会被 tableSizeFor()
调整为 1024
,但是它只是表示 table
数组为 1024
,扩容的重要依据扩容阈值会在 resize()
中调整为 768(1024 * 0.75)
。
它是不足以承载 1000
条数据的,最终在存够 1k
条数据之前,还会触发一次动态扩容
。
Question
: 那构造时传多少才能让HashMap存1000条数据不需要动态扩容呢?
我们可以反推一下:
若 thresholdNew * 0.75 > 1000
,则 thresholdNew > 1333.3
。
而我们上面分析构造传1000
的时候,thresholdNew
会被 tableSizeFor()
调整为 1024
,1024 < 1333.3
不满足。
又我们知道了 tableSizeFor()
这个方法返回大于输入参数且最接近的2的整数次幂的数
,则我们构造时传入1024~2048
之间的数,就会保证HashMap存1000条数据不需要动态扩容
。
Question
: 那构造时传10000是否能让HashMap存10000条数据不需要动态扩容呢?
答案是可以
的。
what?上面1000
的就不行,10000
就可以满足不需要动态扩容了?
别着急,按照我们上面分析的一步一步来。
当我们构造传10000
时,实际上经过 tableSizeFor()
方法处理之后,就会变成 2
的 14
次幂 16384
,再算上负载因子 0.75f
,实际在不触发扩容的前提下,可存储的数据容量是 12288(16384 * 0.75f)
。完全可以存储10000
条数据。
HashMap
构造方法传递的initialCapacity
,虽然在处理后被存入了threshold
中,但它实际表示table
的容量。- 构造方法传递的
initialCapacity
,最终会被tableSizeFor()
方法动态调整为2
的N
次幂,以方便在扩容的时候,计算数据在newTable
中的位置。 - 如果设置了
table
的初始容量,会在初始化table
时,将扩容阈值threshold
重新调整为table.size * loadFactor
。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
戳我获取!!**](https://bbs.csdn.net/topics/618164986)
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!