使用 HashMap 存一万条数据,构造时传 10000 还会触发扩容吗?

”准备用HashMap存1w条数据,构造时传10000会触发扩容吗?“ 构造10000 /** * Constructs an empty <tt>HashMap</tt> with the specified initial * capacity and the default load factor (0.75). * * @param initialCapacity the initial cap... 阅读详情

问题

  向 HashMap 中存 10000 条数据,初始化时,构造方法传值 10000,会触发扩容吗?

Map<String,String> map = new HashMap<>(10000);

分析

乍一看

  肯定会触发扩容呀,因为 HashMap 中有个负载因子默认为 0.75,就是说存储的数量超过容量的 75% 就会触发扩容,put 到后 25% 的数据时,肯定就会触发扩容。但事实真是这样吗?源码中有我们想知道的一切,真相只有一个。

分析源码

HashMap 的初始化

  在 HashMap 中,提供了一个指定初始容量的构造方法 HashMap(int initialCapacity),这个方法再通过 DEFAULT_LOAD_FACTOR 调用 HashMap 另一个构造方法,初始化 loadFactor 为 0.75。

public HashMap(int initialCapacity) {
    this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
  	......
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}

  构造方法初始化了两个成员变量 threshold 和 loadFactor,其中 threshold 就是用来存储触发 HashMap 扩容的阈值,也就是说,当 HashMap 存储的数据量达到 threshold 时,就会触发扩容。
  从改造方法中可以看出,threshold 并没有直接使用传入的 initialCapacity 作为扩容阈值,而是通过 tableSizeFor 方法处理后再赋值给 threshold。

static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

  这啥呀?看不懂也没关系,我来解释。tableSizeFor 的作用就是寻找大于 cap 的 2 的整数次方,例如如果传入 10,经过 tableSizeFor 处理后返回 16。至于为什么这样做,不在此处详细讨论。

回归正题

  还有一个问题,一直在说 threshold 是触发扩容的阈值,即 (initialCapacity * loadFactor),但是我们再构造方法中使用 tableSizeFor 初始化 threshold,并没有用到 loadFactor,其实这一步被移交给 resize 方法实现了,因为我们并没有在构造方法中初始化哈希表数组,扩容阈值 threshold = initialCapacity * loadFactor,这一步在 resize 中完成。
  如果我们从外部传递进来 10000 初始化 initialCapacity ,实际上经过 tableSizeFor 方法处理之后,最终 threshold 就会变成 2 的 14 次幂 16384,再在 resize 方法中乘上负载因子 0.75,实际在不触发扩容的前提下,可存储的数据容量是 12288(16384 * 0.75),用来存放 10000 条数据,绰绰有余,所以并不会触发扩容。

initialCapacity

  关于如何选择 initialCapacity,我们看看阿里巴巴 Java 开发规范,规范要求在初始化 HashMap 时,必须指定 initialCapacity,因为这样可以减少 resize 次数,提高程序效率。因为 threshold = initialCapacity * loadFactor,所以 initialCapacity = (需要存储元素个数 / loadFactor) + 1。
在这里插入图片描述

示例

  想要使用 HashMap 存放 10000 条数据,应该设置 initialCapacity = 10000 / 0.75 + 1 = 13334,然后哈希表容量会被 tableSizeFor 方法调整到 16384(2^14),threshold = 16384 * 0.75 = 12288 足够存储 10000 条数据而不会触发扩容。

总结

  • HashMap 构造方法传递的 initialCapacity 实际表示哈希表的容量,不代表扩容阈值。
  • 构造方法传递的 initialCapacity,会被 tableSizeFor 方法调整为大于它的 2 的整数次方。
  • 如果使用 initialCapacity 进行初始化,HashMap 是否扩容,由 threshold 决定,扩容阈值 threshold = initialCapacity * loadFactor。
  • 在初始化 HashMap 时,必须指定 initialCapacity 来提升效率,initialCapacity = (需要存储元素个数 / loadFactor(默认0.75)) + 1。
sentaurus学习笔记(VDMOS仿真)(三) 在Sentaurus中,这通常意味着在2D仿真中,x轴指向下,y轴指向右。定义了在2D模拟中,网格尺寸按照一定的增长率进行扩展,这里的增长率为2.0,意味着远离最小尺寸区域的网格单元大小将是最小尺寸的两倍。定义了2D模拟中网格单元的最小尺寸为0.001微米,这有助于控制网格的最小大小,从而影响仿真的精度和计算成本。表示启用中等级别的日志信息输出,这有助于用户了解仿真过程中发生的事件和可能的问题。表示启用保存调试文件,这可以帮助用户在仿真过程中检查和验证模型的状态。这行代码设置了仿真过程中使用的线程数。 阅读详情

相关推荐

OpenCV透视变换实战:5分钟搞定歪斜证件照矫正(附完整代码)

本文详细介绍了如何使用OpenCV的透视变换技术快速矫正歪斜证件照,包含完整的Python代码实现。通过特征检测、坐标计算和矩阵变换三个核心步骤,5分钟内即可将手机拍摄的歪斜图像自动矫正为专业级证件照,大幅提升图像处理效率。

weixin_29094979的博客 481

面试官:准备用HashMap存1w条数据,构造时传10000还会触发扩容吗?

// 预计存入 1w 条数据,初始化赋值 10000,避免 resize。 HashMap<String,String> map = new HashMap<>(10000) // for (int i = 0; i < 10000; i++) Java 集合的扩容 HashMap 算是我们最常用的集合之一,虽然对于 Android 开发者,Google 官方推荐了更省内存的 SparseArray 和 ArrayMap,但是 HashMap 依然是最常用的...

小小时光 887

Unity URP热扭曲效果实战:如何让半透明物体也‘动’起来(附完整Shader代码)

本文深入解析Unity URP管线中热扭曲效果无法影响半透明物体的核心原因,并提供一套完整的实战解决方案。通过编写自定义Shader,并巧妙利用URP的Render Objects渲染器功能,成功让指定半透明物体(如粒子特效)也能被扭曲效果影响,从而制作出火焰、热浪等更具视觉冲击力的特效。文末附有完整的Shader代码与进阶优化技巧。

pz890123的博客 501

Java 500M的表,约1千万的数据放在HashMap里面大约占用内存多大?给多大内存最保险?...

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34266504的博客 1991

(一)ANSYS WORKBENCH实践入门

ANSYS-workbench 有限元分析应用基础教程 (张晔)学习笔记

qq_51767372的博客 1万+

路径规划:D*Lite寻路算法详解

D*Lite详解目录

mkr67n的博客 2万+

蚂蚁金服Java研发岗二面:说说HashMap 中的容量与扩容实现

JDK1.8 中 HashMap 的底层实现,我相信大家都能说上来个 一二,底层数据结构 数组 + 链表(或红黑树) ,源码如下 /** *数组 */ transientNode<K,V>[]table;/** *链表结构 */ staticclassNode<K,V>implementsMap.Entry<K,V>{ finalinthash; finalKkey; Vvalue;Node<K...

文章中资料均可获取,有需要请添加yunduoa2019即可 717

C#操作SQLite数据库帮助类——SQLiteHelper

using System; using System.Collections.Generic; using System.Data.SQLite; using System.Data; namespace Com.ZCWL.Rock.Helper { public class SQLiteHelper { private static string connectionString =

跟健哥出去走走 2万+

HashMap源码注解和相关面试问题汇总答疑

整合网上摘抄的和自己的理解 一、相关参数 1、默认初始容量 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 必须是2的n次幂 2、负载因子 DEFAULT_LOAD_FACTOR = 0.75f; 3、扩容阀值 int threshold; (容量capacity*负载因子load factor),当...

ggf的专栏 272

UNext:基于 MLP 的快速医学图像分割网络

有代码,可深入学习轻量级分割模型的论文切入点 UNet 及其最新扩展(如 TransUNet)近年来一直是领先的医学图像分割方法。然而,这些网络无法有效地用于应用中的快速图像分割,因为它们参数繁重、计算复杂且使用缓慢。为此,我们提出了 UNeXt,它是一种基于卷积多层感知器(MLP)的图像分割网络。我们以有效的方式设计了 UNeXt,其中包括早期卷积阶段和潜在阶段的 MLP 阶段。我们提出了一个标记化的 MLP 块,我们可以在其中有效地标记和投影卷积特征,并使用 MLP 来对表示进行建模。

Philo的博客 3942

Allegro如何画Photoplot_Outline操作指导

在用Allegro进行PCB设计的时候,最后进行光绘输出前,Photoplot_Outline是必备一个图形,所有在Photoplot_Outline中的图形将被输出,Photoplot_Outline以外的图形都将不被输出。如何绘制Photoplot_Outline,具体操作如下。如何画Photoplot_Outline操作指导。

weixin_54787054的博客 2633

面试官:”准备用HashMap存1w条数据,构造时传10000会触发扩容吗?“

//预计存入1w条数据,初始化赋值10000,避免 resize。 HashMap<String,String>map=newHashMap<...

承香墨影的博客 3659

内存越界一定会导致程序崩溃吗?详解内存越界

本文详细解释了内存越界不一定导致内存越界的问题,全面介绍了C++内存越界的相关内容。

dvlinker的技术专栏 2万+

准备用HashMap存1W条数据,构造时传10000还会触发扩容吗?存1000呢?

准备用HashMap存1W条数据,构造时传10000还会触发扩容吗?存1000呢?

Knight 1376

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

面试官:"准备用HashMap存1w条数据,构造时传10000还会触发扩容吗?"

// 预计存入 1w 条数据,初始化赋值 10000,避免 resize。 HashMap<String,String> map = new HashMap<>(10000) // for (int i = 0; i < 10000; i++) Java 集合的扩容 HashMap 算是我们最常用的集合之一,虽然对于 Android 开发者,Google 官方推...

good575654643的博客 5829

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

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

既已说到spring cloud alibaba,那对于整个微服务架构,如果想要进一步地向上提升自己,到底应该掌握哪些核心技能呢?就个人而言,对于整个微服务架构,像RPC、Dubbo、Spring Boot、Spring Cloud Alibaba、Docker、kubernetes、Spring Cloud Netflix、Service Mesh等这些都是最最核心的知识,架构师必经之路!下图,是自绘的微服务架构路线体系大纲,如果有还不知道自己该掌握些啥技术的朋友,可根据小编手绘的大纲进行一个参考。

2301_82242844的博客 899

使用容量 10000 的HashMap 存9000条数据,会触发扩容吗 ?

面试官:使用容量 10000 的HashMap 存9000条数据,会触发扩容吗 ? 先说结论,不会! 众所周知,Hashmap有负载因子为0.75,达到负载因子就会触发扩容,但这是无参构造即初始容量为16的Hashmap,而这里容量是10000,使用了有参构造的Hashmap,不一样。

机械工程跑路哥 1493

面试官:“准备用HashMap存1w条数据,构造时传10000还会触发扩容吗?“

https://juejin.im/post/6844903983748743175 https://www.jianshu.com/p/6d7151c2a700 //预计存入1w条数据,初始化赋值10000,避免resize。 HashMap<String,String>map=newHashMap<>(10000) //for(inti=0;i<10000;i++) 复制代码 Java 集合的扩容 Ha...

yb223731的博客 1039

面试官:_准备用HashMap存1w条数据,构造时传10000还会触发扩容吗?_

看到这篇文章的人不知道有多少是和我一样的Android程序员。35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

2401_86022640的博客 734

hashmap扩容_涉及源码:准备用HashMap存1W条数据,构造时传10000还会触发扩容吗?存1000呢?...

本篇文章先写的一下涉及到的hashmap的一点源码的东西,后期有时间写出完整的hashmap的原码过程,19年冬天的时候完成的一步一步的看了一下jdk1.8的hashmap的源码和courrenthashmap的源码,先根据一个小需求简单介绍一下!HashMap真的是用处非常广泛,首先,费话不多说,我自己打开了idea,并进入HashMap的构造方法可见,HashMap提供了一个指定初始容量的构造...

weixin_39819661的博客 481

hashmap存多少条数据_准备用 HashMap 存储 1w 条数据,构造方法传入 1w 进去会触发扩容吗?...

通过构造方法传入 1w,也就是 Map map = new HashMap(10000),想要知道它是否会扩容,那就看这个构造方法做了啥?public HashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);}调用了自身的另一个构造方法public HashMap(int initialCapacity, f...

weixin_30444697的博客 1162

table高度改变时触发什么事件_面试官:”准备用HashMap存1w条数据,构造时传10000会触发扩容吗?“...

阖(xin)家(jing)团(dan)圆(zhan)的春节假期结束了,我们需要点技术干货充实下自己~本篇文章介绍了集合扩容的相关干货,5分钟时间即可通读全文~//预计存入1w条数据,初始化赋值10000,避免 resize。HashMapmap=newHashMap<>(10000)//for(inti=0;iJava 集合的扩容HashMap 算是我...

weixin_39574287的博客 83

table高度改变时触发什么事件_面试官:"准备用HashMap存1w条数据,构造时传10000还会触发扩容吗?"...

Java 集合的扩容HashMap 算是我们最常用的集合之一,虽然对于 Android 开发者,Google 官方推荐了更省内存的 SparseArray 和 ArrayMap,但是 HashMap 依然是最常用的。我们通过 HashMap 来存储 Key-Value 这种键值对形式的数据,其内部通过哈希表,让存取效率最好时可以达到 O(1),而又因为可能存在的 Hash 冲突,引入了链表和红黑树...

weixin_39797324的博客 75
上一篇: 浅析 Comparable 和 Comparator
下一篇: Java 为什么不支持泛型数组?
ali48
博客等级 码龄6年 31粉丝 117原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值