HashMap存1000条数据,构造时传多少才能让HashMap不需要动态扩容?

当我们首次调用 HashMapput() 方法存数据时,如果发现 tablenull,则会调用 resize() 去初始化 table,具体逻辑在 putVal() 方法中。

在这里插入图片描述

resize() 方法中,调整了最终 threshold 值,以及完成了 table 的初始化。

在这里插入图片描述

因为 resize() 还糅合了动态扩容的逻辑,所以我将初始化 table 的逻辑用注释标记出来了。其中 xxxCapxxxThr 分别对应了 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() 调整为 10241024 < 1333.3不满足。

又我们知道了 tableSizeFor() 这个方法返回大于输入参数且最接近的2的整数次幂的数,则我们构造时传入1024~2048之间的数,就会保证HashMap存1000条数据不需要动态扩容

三、举一反三


Question: 那构造时传10000是否能让HashMap存10000条数据不需要动态扩容呢?

答案是可以的。

what?上面1000的就不行,10000就可以满足不需要动态扩容了?

别着急,按照我们上面分析的一步一步来。

当我们构造传10000时,实际上经过 tableSizeFor() 方法处理之后,就会变成 214 次幂 16384,再算上负载因子 0.75f,实际在不触发扩容的前提下,可存储的数据容量是 12288(16384 * 0.75f)。完全可以存储10000条数据。

四、小结


  • HashMap 构造方法传递的 initialCapacity,虽然在处理后被存入了 threshold 中,但它实际表示 table 的容量。
  • 构造方法传递的 initialCapacity,最终会被 tableSizeFor() 方法动态调整为 2N 次幂,以方便在扩容的时候,计算数据在 newTable 中的位置。
  • 如果设置了 table 的初始容量,会在初始化 table 时,将扩容阈值 threshold 重新调整为 table.size * loadFactor

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
戳我获取!!**](https://bbs.csdn.net/topics/618164986)

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值