首页 > 其他分享 >HashMap 的初始化问题

HashMap 的初始化问题

时间:2023-09-16 18:23:00浏览次数:27  
标签:初始化 newCap HashMap 容量 问题 数组 threshold

最近的两次面试被分别被问到了:

如果初始化 HashMap 的容量为 100,那么实际容量会是多少?

如果初始化 HashMap 的容量为 20,那么实际容量会是多少?会不会发生扩容?

自己想当然的会回答:容量会是满足 2 的幂次 * 负载因子 >= 初始化指定容量的值

public static void main(String[] args) {
    Map<String,Integer> map = new HashMap<>(100);
    System.out.println(map.size());// 0
    map.put("1",2);
    System.out.println(map.size());// 1
}

但是这好像是彻底错误的,于是去检查源码探究这个问题

构造函数

当使用构造函数创建 HashMap 时,发现 4 个构造函数中,抛开一个以 Map 为参数的,另外三个分别是:

  • 无参
  • 指定容量
  • 指定容量和负载因子

而事实上这三个方法中都并没有去创建实际的桶数组,而只是指定了两个参数:负载因子loadFactorthreshold

threshold表示数组被初始化之前可以容纳的元素数量的阈值

那么具体的创建又是在哪里实现的呢?

put()函数

以初始化指定容量 20 为例:new HashMap(20),在构造方法中会指定两个属性:

  1. 负载因子loadFactor:未指定则为默认值0.75
  2. threshold为大于 20 的最小的 2 的幂数,也就是32

但是此时,这个数组是没有被创建的,也就是说实际的桶数组是null不存在的

只有当向 map 中put()元素的时候,才回去检查数组是否为null并初始化

put()方法的实际实现putVal()方法中

if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;

判断到数组为空,会有第一次扩容

因为此时旧容量为 0,新容量会被指定为旧 threshold

if (oldCap > 0) {}
else if (oldThr > 0) newCap = oldThr;

这里还回去计算新的threshold,在不超过最大容量的情况下,会变成 newCap*loadFactor

if (newThr == 0) {
    float ft = (float)newCap * loadFactor;
    newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
              (int)ft : Integer.MAX_VALUE);
}

并最终将这个数组创建出来,这个返回的底层实际数组的大小为 32

Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];

后续put()过程中发生的扩容参考则变成了threshold

if (++size > threshold) resize();

标签:初始化,newCap,HashMap,容量,问题,数组,threshold
From: https://www.cnblogs.com/yaocy/p/17706595.html

相关文章

  • winform 解决 下拉框数据显示问题
    数据源刷新:在使用winform下拉框时,绑定的数据不会随着刷新(只试过绑定集合等类,不涉及数据库)解决办法是:先赋null值,然后再绑定 此外,当多个下拉框同时是一个集合的范围但是操作是给另一个类属性赋值时,其中一个下拉框改变会导致其他下拉框跟着改变解决办法是:绑定一个与......
  • 前端学习笔记202308学习笔记第八十伍天-样式初始化
        ......
  • 前端学习笔记202308学习笔记第八十伍天-目录初始化
     ......
  • WPF使用WebView2的空域问题的解决方案
    我在之前文章中介绍过WPF使用WebView2的空域问题(Airspaceissuse),距离那篇文章大半年后,那个issue下有一个第好用的第三方解决方案了,我这里介绍一下。引入Microsoft.Web.WebView2组件,同时引入CrissCross.WPF.WebView2组件<ItemGroup><PackageReferenceInclude="CrissCross.......
  • winform 解决 窗体清晰度问题
    在C#中让Winform应用程序窗口自动适应高DPI缩放不使用其他特殊组件库的情况下添加清单文件在末尾添加:<applicationxmlns="urn:schemas-microsoft-com:asm.v3"><windowsSettings><dpiAwarexmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true&l......
  • 页面中点击按钮需要新建轮播(需要新建多个),出现顺序错乱的问题
    当页面中通过点击按钮切换轮播,即点击按钮需要newswiper,新建后,页面中swiper内容没有问题但是,点击上一个下一个按钮,顺序会发生错乱 在new之前需要使用destroy销毁 ......
  • XMind2TestCase安装问题
     安装完成了XMind2TestCase之后,在命令端检查安装是否成功,报错:C:\Users\Administrator>xmind2testcaseTraceback(mostrecentcalllast): File"C:\Softwares\Python\Scripts\xmind2testcase-script.py",line33,in<module> sys.exit(load_entry_point('......
  • 华为应用市场上架 视频介绍上传 遇到的问题解决
    昨天在华为应用市场上架应用, 视频介绍上传时, 一直是视频加载中,百思不得其解. 虽然不是第一次上传视频了,怎么这次遇到这个问题.偶然发现在视频介绍上传时, 选择海报后,一定要下划,点击确认,才能完成上传!否则一直是视频加载中............
  • 练习:经典问题--n 以内的质数
    题:请找出n以内的所有质数(不包括n)。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数如,n=100输出:[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]1classSolution(object):2deffunc(self,n):......
  • 解决wangEditor从word复制粘贴图片,带有页眉页脚的问题
    话不多说,直接贴代码。rtf数据能提取到页眉页脚图片的原因:提取Word文档中包含的所有图像数据,包括页眉和页脚中的图像数据。这是因为RTF(RichTextFormat)是一种标记语言,可以在其中嵌入文本、图像和其他媒体类型的数据。在Word中,页眉和页脚的内容也可以通过RTF格式进行描述......