当前位置: 首页 > news >正文

Java HashMap 扩容机制深度解析

HashMap 的一个关键性能优化就是扩容机制,即在哈希表达到一定负载因子时,自动进行扩容,以保持检索效率。

在这篇文章中,我们将深入研究 HashMap 的扩容机制,了解其原理和影响因素。

1. 初始容量和负载因子

在深入了解 HashMap 的扩容机制之前,我们先了解一下 HashMap 的构造函数中的两个重要参数:

初始容量和负载因子。

public HashMap(int initialCapacity, float loadFactor)

1.1 initialCapacity(初始容量)

表示 HashMap 创建时的容量大小。默认为16,但可以根据预估的元素数量进行调整,以减少扩容次数。

1.2 loadFactor(负载因子)

表示哈希表在达到多少比例的容量时进行扩容。默认为0.75,即当哈希表的实际元素数量达到容量的 75% 时触发扩容。

2. 哈希表和负载因子的关系

HashMap 通过调整负载因子来平衡空间利用率和查找性能。

负载因子越大,哈希表的容量利用率越高,但可能导致哈希冲突增多;负载因子越小,哈希表的容量利用率越低,但减少了哈希冲突的可能性。

3. 扩容触发条件

HashMap 在什么情况下触发扩容呢?当哈希表中的元素数量达到负载因子与当前容量的乘积时,触发扩容操作。

具体公式为:

size > capacity * loadFactor

这时,HashMap 会将容量扩大为当前容量的两倍,并将原有的元素重新分配到新的哈希桶中。

4. 扩容过程

HashMap 的扩容过程并非简单地将数组大小翻倍。具体来说,扩容分为以下几个步骤:

4.1 创建新的哈希表数组

新的容量是原来容量的两倍,并且是大于等于当前元素数量除以负载因子的最小的2的幂。

int newCapacity = oldCapacity << 1;
while (newCapacity < size / loadFactor) {newCapacity <<= 1;
}

数组初始化值是 16,元素达到 12 时进行扩容,2 倍进行扩容后为 32。

4.2 迁移元素

将原哈希表中的元素重新计算哈希码并放入新的哈希表中。

//遍历旧数组
for (int j = 0; j < oldCap; ++j) {Node<K,V> e;if ((e = oldTab[j]) != null) {oldTab[j] = null;if (e.next == null)//hash、数组大小,进行与运算newTab[e.hash & (newCap - 1)] = e;else if (e instanceof TreeNode)((TreeNode<K,V>)e).split(this, newTab, j, oldCap);else { // preserve order//.......}}
}

重新 hash 计算,我们看到 JDK 采用的是与运算,没有采用取模计算,与运算效率更高。

4.3 替换旧的哈希表

扩容完成后,将新的哈希表替换为原来的哈希表。

table = newTable;

5. 扩容过程的性能影响

HashMap 的扩容虽然为了维持性能,但在扩容过程中可能引起性能波动。

在扩容期间,如果有其他线程正在对 HashMap 进行并发修改,可能会导致遍历不一致性或者链表/红黑树的结构异常。这也是为什么在多线程环境中建议使用 ConcurrentHashMap。

6. 性能优化建议

为了减少扩容次数,我们可以在创建 HashMap 时提前设定足够的初始容量。这样可以减少哈希冲突的可能性,延缓扩容操作的发生。

Map<String, Integer> map = new HashMap<>(1024, 0.75f);

总结

通过深入了解 HashMap 扩容原理,合理选择初始容量和负载因子,负载因子参数一般不建议修改,注意并发修改可能引起的问题,都是使用 HashMap 时需要考虑的重要因素。

希望今天的内容对初学 Java 的朋友有所启发或者帮助。各位,有帮助点个赞或在看呀:-),这对我非常重要。

相关文章:

Java HashMap 扩容机制深度解析

HashMap 的一个关键性能优化就是扩容机制&#xff0c;即在哈希表达到一定负载因子时&#xff0c;自动进行扩容&#xff0c;以保持检索效率。 在这篇文章中&#xff0c;我们将深入研究 HashMap 的扩容机制&#xff0c;了解其原理和影响因素。 1. 初始容量和负载因子 在深入了解…...

一、Electron 环境初步搭建

新建一个文件夹&#xff0c;然后进行 npm init -y 进行初始化&#xff0c;然后我们在进行 npm i electron --save-dev , 此时我们按照官网的教程进行一个初步的搭建&#xff0c; 1.在 package.json 文件进行修改 {"name": "electron-ui","version…...

ffmpeg编码器编码元数据的过程以及编码前后的差异

编码方式为avcodec_send_frame&#xff1a;将原始帧发送到编码器进行编码 编码过程完成于avcodec_receive_packet&#xff1a;从编码器接收编码后的压缩数据&#xff0c;也就是说已经编码压缩完成了&#xff0c;并存储到avpacket中&#xff0c;此时元数据被分割成多个NALU单元&…...

AB测试学习(附有相关代码)

目录 一、基本概念1. 定义2. 作用3. 原理 二、实验基本原则三、实验步骤四、实验步骤详解1. 确定实验目的2. 确定实验变量3. 实验指标设计3.1 实验指标类型&#xff08;按作用区分&#xff09;3.1.1 核心指标3.1.2 驱动指标&#xff08;跟踪指标&#xff09;3.1.3 护栏指标 3.2…...

用idea将java文件打成jar包

一、用idea将java文件打成jar包 1、在idea上选择file—Project Structure 2、Artifacts —点–JAR—From modules with dependencies 3、选择要打包的java文件 4、Build — Build Artifacts 5、找到刚才添加的Artifacts直接Build 6、生成jar包文件...

Ansible——group模块

目录 参数总结 语法示例 创建用户组 删除用户组 设置组的 GID 创建系统组 修改组的 GID 添加用户组并附加其他组属性 删除指定 GID 的用户组 帮助信息 Playbook示例 基本示例 1. 创建用户组 2. 删除用户组 进阶示例 1. 修改组的 GID 2. 综合管理多个用户组 3…...

Sql注入-报错注入

报错注入&#xff08;Error-Based Injection&#xff09;是一种通过引起数据库报错并从错误信息中提取有用信息的SQL注入攻击手法&#xff1b;攻击者利用数据库在处理异常情况时返回的错误消息&#xff0c;来推断出数据库结构、字段名甚至数据内容&#xff1b;这种攻击方法依赖…...

pyqt 回车触发两次editingFinished的解决办法

在英文Qt论坛看到的解决办法 def editingFinished_triger(self):#self.sender() is the QlineEditif not self.sender().isModified(): returnself.sender().setModified(False)#treat code ...#treat code ...下面是一个错误使用editingFinished的例子 在上面界面中有一个文本…...

爬取股票数据python

最近在搜集数据要做分析&#xff0c;一般的数据来源是一手数据&#xff08;生产的&#xff09;和二手数据&#xff08;来自其他地方的&#xff09;。 今天我们爬取同花顺这个网站的数据。url为&#xff1a;https://data.10jqka.com.cn/ipo/xgsgyzq/ 话不多说直接上代码。有帮…...

每日新闻掌握【2024年6月4日 星期二】

2024年6月4日 星期二 农历四月廿八 TOP大新闻 张雪峰近2万元志愿填报服务已售罄 2024年高考临近&#xff0c;考生紧张的是考场上能否如常发挥&#xff0c;而考场之下&#xff0c;家长们已经开始为孩子的志愿填报焦心。峰学蔚来是由张雪峰打造专门提供高考志愿填报服务的APP&am…...

智谱AI 发布最新开源模型GLM-4-9B,通用能力超Llama-3-8B,多模态版本比肩GPT-4V

自 2023 年 3 月 14 日开源 ChatGLM-6B 以来&#xff0c;GLM 系列模型受到广泛关注和认可。特别是 ChatGLM3-6B 开源以后&#xff0c;开发者对智谱AI 第四代模型的开源充满期待。 为了使小模型&#xff08;10B 以下&#xff09;具备更加强大的能力&#xff0c;GLM 技术团队进行…...

从写简历到谈薪资的最全教程

从写简历到谈薪资的最全教程 目录简历注意事项举个例子写简历投递简历也有技巧模拟面试的重要性面试经验怎么刷不断迭代达越来越强斗智斗勇谈薪资拿到offer就结束了吗&#xff1f;我能给你的帮助 目录 大家好&#xff0c;我是一名普通本科毕业的学生&#xff0c;工作数年&#…...

Vue3 响应式API:高级函数(二)

shallowRef() shallowRef 是一个特殊的 ref 创建函数&#xff0c;它允许你创建一个只追踪顶层属性变化的响应式引用。与 ref 不同的是&#xff0c;shallowRef 创建的响应式引用对其内部值的深层嵌套属性是不敏感的&#xff0c;也就是说&#xff0c;只有当 shallowRef 的 .valu…...

『大模型笔记』什么是提示词注入(Prompt Injection)攻击?

什么是提示词注入(Prompt Injection)攻击? 文章目录 一. 什么是提示词注入(Prompt Injection)?二. 参考文献一. 什么是提示词注入(Prompt Injection)? 想花1美元买一辆新SUV吗?有人真的尝试过这样做。事实上,他们在一家特定汽车经销商的网站聊天机器人上进行了尝试。为了…...

SD-WAN与IPSec的对比

在现代企业中&#xff0c;随着网络环境的日益复杂&#xff0c;SD-WAN和IPSec作为两种关键的网络技术&#xff0c;各有其独特的优势和应用场景。那么&#xff0c;SD-WAN和IPSec究竟有什么不同&#xff1f;企业在不同情况下应该选择哪种技术呢&#xff1f; SD-WAN和IPSec的基本概…...

Ceph入门到精通-ceph经典盘符飘逸问题处理步骤

在Ceph存储系统中,"盘符飘逸"通常指的是Ceph OSD(Object Storage Daemon)使用的磁盘在系统重启后没有被正确挂载或识别。这可能是由于多种原因造成的,例如磁盘连接问题、驱动问题或配置错误。以下是解决此问题的步骤: 确认磁盘状态: 使用lsblk或fdisk -l命令来…...

【CV算法工程师必看】作为一个图像算法工程师,需要会什么,要学哪些技术栈?

作为一个图像算法工程师,除了基本的编程技能和理论知识,还需要掌握一系列的技术栈。以下是详细的技能和技术栈分类: 编程语言 Python: 主要用于快速开发和原型设计。常用库:OpenCV、Pillow、NumPy、SciPy、Scikit-image、TensorFlow、PyTorch。C++: 高性能要求的项目中广…...

【造化弄人:计算机系大学生真的象当年的高速公路收费员一样吗?】

曾经高速公路的收费员是多么的自豪和骄傲&#xff0c;按照常逻辑&#xff0c;车是越来越多&#xff0c;收费员应该越来越多&#xff1f;但现实情况&#xff0c;大家有目共睹&#xff01; 不论你的车子怎么跑&#xff0c;只要上高速就要交费&#xff0c;那时候的收费员&#xf…...

民主测评要做些什么?

民主测评&#xff0c;作为一种重要的民主管理工具&#xff0c;旨在通过广泛征求群众意见&#xff0c;对特定对象或事项进行客观、公正的评价。它不仅是推动民主参与、民主监督的重要手段&#xff0c;也是提升治理效能、促进社会和谐的有效途径。以下将详细介绍民主测评的主要过…...

JimuReport 积木报表 v1.7.5 版本发布,免费的低代码报表

项目介绍 一款免费的数据可视化报表工具&#xff0c;含报表和大屏设计&#xff0c;像搭建积木一样在线设计报表&#xff01;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; Web 版报表设计器&#xff0c;类似于excel操作风格&#xff0c;通过拖拽完…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》

&#x1f9e0; LangChain 中 TextSplitter 的使用详解&#xff1a;从基础到进阶&#xff08;附代码&#xff09; 一、前言 在处理大规模文本数据时&#xff0c;特别是在构建知识库或进行大模型训练与推理时&#xff0c;文本切分&#xff08;Text Splitting&#xff09; 是一个…...