HashMap添加元素的流程图
文章目录
- JDK7 vs JDK8 的 HashMap 结构变化
- Java8 中哈希表的红黑树优化机制
- HashMap 添加元素的完整流程解析
- 1. 计算 key 的哈希值并确定索引
- 2. 检查该索引位置是否已有元素
- 3. 处理哈希冲突
- 4. 判断当前存储结构(链表还是红黑树)
- 5. 判断链表长度是否超过 8
- 6. 触发扩容的判断
- 7. 进行扩容
- 8. 迁移元素
- 流程图
- 补充
- HashMap 的初始容量与负载因子优化
JDK7 vs JDK8 的 HashMap 结构变化
在 JDK7 及更早版本,HashMap 采用 数组 + 链表 结构,当哈希冲突较多时,链表可能变得很长,导致查询性能从 O(1) 退化到 O(n)。
在 JDK8,为了优化链表查询性能,引入了红黑树:
- 仍然采用 数组 作为底层存储。
- 当某个桶中的链表长度 超过 8,并且 table 的大小 ≥ 64 时,链表转换为
红黑树。 - 这样,在极端情况下,查询性能从 O(n) 降低到
O(log n)。
Java8 中哈希表的红黑树优化机制
从JDK8开始,为了优化哈希冲突情况下的查找性能,当哈希桶中的链表长度超过 8 时,链表会转换为红黑树。红黑树是一种自平衡二叉搜索树,将最坏情况下的查找复杂度从 O(n) 降低到 O(log n)。(如果没引入红黑树,则最坏查找复杂度是O(n))
当树中元素数量低于 6 时,红黑树会退化回链表,以减少不必要的树操作开销,提高小规模数据场景下的性能。
HashMap 添加元素的完整流程解析
1. 计算 key 的哈希值并确定索引
- 通过
key.hashCode()计算出哈希值。 - 采用
(哈希值 & (table.length - 1))计算索引,以确定 key 应该存放在table数组中的那个位置。
2. 检查该索引位置是否已有元素
- 如果该索引位置为空(
table[index] == null),说明当前 key 没有发生哈希冲突,直接存入该位置,并检查是否需要扩容。【在 HashMap 里,负载因子(loadFactor)默认值是 0.75,表示当元素个数达到 容量 * 0.75 时,就会触发扩容】 - 如果该索引位置已有元素,说明发生了哈希冲突,进入下一步处理。
3. 处理哈希冲突
在索引位置已有元素的情况下,需要判断该 key 是否已经存在:
- 如果 key 与已有节点的 key 相同,说明是更新操作,直接替换
value。 - 如果 key 不同,说明该索引位置是个链表或红黑树,需要进一步处理。
4. 判断当前存储结构(链表还是红黑树)
- 如果该索引处存储的是红黑树,按照红黑树的插入规则执行插入操作,流程结束。
- 如果是链表,则遍历链表:
- 如果链表中存在相同的 key,则更新
value,流程结束。 - 如果链表中没有相同 key,则在链表末尾插入新节点,并继续下一步处理。
- 如果链表中存在相同的 key,则更新
5. 判断链表长度是否超过 8
- 如果链表长度 ≤ 8,不做额外处理。
- 如果链表长度 > 8,则需要判断是否转换为红黑树:
- 如果
table长度 >= 64,则将链表转换为红黑树,流程结束。 - 如果
table长度 < 64,则不转换为红黑树,而是触发扩容(见步骤 7)。
- 如果
6. 触发扩容的判断
在完成插入后,需要判断是否需要扩容:
size >= 阈值(threshold = table.length * 0.75)时触发扩容。- 扩容是基于整个 HashMap 的大小,而不是单个链表的长度,即使单个链表过长,也不会单独扩容,而是考虑整体
size。
7. 进行扩容
- 扩容策略:
table容量翻倍(如16 → 32,32 → 64)。 - 调整扩容阈值:新阈值 =
新容量 * 0.75。 - 重新计算 key 的索引:
- 由于
table.length发生变化,所有 key 需要重新计算索引并迁移到新的table。 HashMap采用高位 & 低位拆分的方式优化了 rehash 过程,使得某些 key 的新索引保持不变,而另一些 key 需要移动到新位置。
- 由于
8. 迁移元素
- 旧
table的数据逐个迁移到新table。 - 迁移规则:
- 计算
oldIndex = hash & (oldCapacity - 1),newIndex = hash & (newCapacity - 1)。 - 低位不变,高位索引变化,减少数据迁移的计算量。
- 计算
流程图

补充
HashMap 的初始容量与负载因子优化
HashMap 的默认初始容量为 16,负载因子为 0.75,这一组合在性能与空间之间取得了平衡。较高的负载因子(如 1.0)可减少空间浪费,但会增加哈希冲突的概率;较低的负载因子则减少哈希冲突,但会增加内存开销。 (如果可预估 HashMap 的存储需求,建议提前设置合适的初始容量,以减少动态扩容带来的性能损耗。)
❤觉得有用的可以留个关注~~❤
相关文章:
HashMap添加元素的流程图
文章目录 JDK7 vs JDK8 的 HashMap 结构变化Java8 中哈希表的红黑树优化机制HashMap 添加元素的完整流程解析1. 计算 key 的哈希值并确定索引2. 检查该索引位置是否已有元素3. 处理哈希冲突4. 判断当前存储结构(链表还是红黑树)5. 判断链表长度是否超过 …...
(八)Set 的使用
Set 的使用 Set 的特点 主要功能:去除重复内容。特性:无序且不支持重复的集合,不能通过索引访问元素。 示例代码 void main() {// 创建一个包含重复元素的列表List<String> fruits [香蕉, 苹果, 西瓜, 香蕉, 苹果, 香蕉, 苹果];//…...
Spring Boot 集成 Kafka 消息发送方案
一、引言 在 Spring Boot 项目中,Kafka 是常用的消息队列,可实现高效的消息传递。本文介绍三种在 Spring Boot 中使用 Kafka 发送消息的方式,分析各自优缺点,并给出对应的 pom.xml 依赖。 二、依赖引入 在 pom.xml 中添加以下依赖: <dependencies><!-- Sprin…...
面向医药仓储场景下的药品分拣控制策略方法 研究(大纲)
面向医药仓储场景下的药品分拣控制策略方法研究 基于多机器人协同与智能调度的分拣系统设计 第一章 绪论 1.1 研究背景与意义 医药仓储自动化需求: 人工分拣效率低、出错率高(如药品批次混淆、过期风险)温控药品(如疫苗、生物制…...
AI大模型介绍
大模型介绍 大模型是指具有大规模参数和复杂计算结构的机器学习模型,通常由深度神经网络构建而成,拥有数十亿甚至数千亿个参数 开发大模型不是从0开始,是建立在已有的大模型基座模型上做开发,构建企业知识库(向量数据库…...
Python日期时间向前向后N个月及对应月初和月末
Python日期和时间的计算主要使用自带的datetime和calendar库,部分需要借助第三方dateutil库。下面具体说明时间的加减运算,月份的起始和结束日期,向前向后移动的时间间隔等,代码如下: from datetime import date, dat…...
OpenPCDet详细部署与复现
OpenPCDet简介 OpenPCDet是一个用于3D目标检测的开源工具箱,它提供了多种数据集的加载器,支持多种模型,并且易于扩展。 本人使用硬件与环境 Linux操作系统(Ubuntu20.04) Python环境(Anaconda下独立创建&…...
同旺科技USB to I2C 适配器 ---- 指令之间延时功能
所需设备: 内附链接 1、同旺科技USB to I2C 适配器 1、指令之间需要延时发送怎么办?循环过程需要延时怎么办?如何定时发送?现在这些都可以轻松解决; 2、只要在 “发送数据” 栏的Delay单元格里面输入相应的延迟时间就…...
网络华为HCIA+HCIP NFV
目录 NFV关键技术:虚拟化 NFV关键技术:云化 NFV架构 NFV标准架构 编辑 NFV架构功能模块 NFV架构接口 NFV关键技术:虚拟化 在NFV的道路上,虚拟化是基础,云化是关键。传统电信网络中,各个网元都是…...
MySQL0基础学习记录-下载与安装
下载 下载地址: (Windows)https://dev.mysql.com/downloads/file/?id536787 安装 直接点next,出现: 点execute 然后一直next到这页: next 然后需要给root设置一个密码: 在next。。很多页…...
【万字总结】前端全方位性能优化指南(五)——HTTP/3+QUIC、0-RTT会话恢复、智能压缩决策树
前言 在5G与边缘计算重塑网络格局的今天,传统TCP协议已成为性能跃迁的最后瓶颈。HTTP/3凭借QUIC协议实现传输层革新,通过UDP多路复用+零RTT握手,在弱网环境下仍可保持90%以上的传输效率,头部企业实测首屏加载时间降低40%。本章聚焦三大突破性实践:从Nginx/K8s集群的HTTP/3…...
集成学习(下):Stacking集成方法
一、Stacking的元学习革命 1.1 概念 Stacking(堆叠法) 是一种集成学习技术,通过组合多个基学习器(base learner)的预测结果,并利用一个元模型(meta-model)进行二次训练,…...
centos 7 搭建FTP user-list用户列表
在 CentOS 7 上搭建基于 user_list 的 FTP 用户列表,你可以按以下步骤操作: 1. 安装 vsftpd 服务 若还未安装 vsftpd,可以使用以下命令进行安装: bash yum install -y vsftpd2. 启动并设置开机自启 vsftpd 服务 bash systemctl…...
CUDA编程面试高频30题
1. 什么是CUDA?它与GPU的关系是什么? 答: CUDA(Compute Unified Device Architecture)是由NVIDIA开发的一种并行计算平台和应用程序接口模型。它允许开发者利用NVIDIA GPU进行通用计算任务,而不仅仅是图形渲染。CUDA提…...
PageHelper插件依赖引入不报错,但用不了
情况: 父模块pom. Xml 引入1. 4. 0以上版本的pagehelper-spring-boot-starter。 要用到插件的子模块,去掉版本号,引入和父模块一样的依赖。 引入成功,没有报错,但是打开右边的maven里面没有找到PageHelper插件。 终端清空并重…...
背包问题——动态规划的经典问题包括01背包问题和完全背包问题
01背包问题:给你多个物品每个物品只能选一次,要你在不超过背包容积(或者恰好等于)的情况下选择装价值最大的组合。如果没有动态规划的基础其实是很难理解这个问题的,所以看这篇文章之前先去学习一下动态规划的基本思想…...
MyBatis 面试专题
MyBatis 面试专题 基础概念MyBatis中的工作原理MyBatis 与 Hibernate 的区别?#{} 和 ${} 的区别?MyBatis 的核心组件有哪些? 映射与配置如何传递多个参数?ResultMap 的作用是什么?动态 SQL 常用标签有哪些?…...
Animation - AI Controller控制SKM_Manny的一些问题
一些学习笔记归档; 在UE5中,使用新的小白人骨骼:SKM_Manny,会跟UE4中的小白人有一些差别; 比如在用AI Controller控制使用该骨骼(配置默认的ABP_Manny Animation BP)角色的时候,需要…...
安科瑞新能源防逆流解决方案:守护电网安全,赋能绿色能源利用
随着光伏、储能等新能源在用户侧的快速普及,如何避免电力逆流对电网造成冲击,成为行业关注的焦点。安科瑞凭借技术实力与丰富的产品矩阵,推出多场景新能源防逆流解决方案,以智能化手段助力用户实现安全、经济的能源管理࿰…...
filebeat和logstash区别
Filebeat 角色: 轻量级日志收集器。 功能: 从指定的日志文件中读取日志数据。 可以从多个源(如文件、系统日志、容器日志等)收集日志。 将收集到的日志数据传输到 Logstash、Elasticsearch 或其他支持的输出端点。 性能: 由于是轻量级的,File…...
【一起学Rust | Tauri2.0框架】基于 Rust 与 Tauri 2.0 框架实现全局状态管理
前言 在现代应用程序开发中,状态管理是构建复杂且可维护应用的关键。随着应用程序规模的增长,组件之间共享和同步状态变得越来越具有挑战性。如果处理不当,状态管理可能会导致代码混乱、难以调试,并最终影响应用程序的性能和可扩…...
扩散模型算法实战——三维重建的应用
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 引言 三维重建是计算机视觉和图形学中的一个重要研究方向,旨在从二维图像或其他传感器数据中恢复…...
社群经济4.0时代:开源链动模式与AI技术驱动的电商生态重构
摘要:在Web3.0技术浪潮与私域流量红利的双重驱动下,电商行业正经历从"流量收割"到"用户深耕"的范式转变。本文基于社群经济理论框架,结合"开源链动21模式"、AI智能名片、S2B2C商城小程序源码等创新工具&#x…...
【Linux系统】进程等待:告别僵尸进程深入理解Linux进程同步的核心密码
Linux系列 文章目录 Linux系列前言一、进程等待的核心目的二、进程等待的实现方式2.1 wait()函数2.2 waitpid()函数 总结 前言 在Linux系统中,进程等待(Process Waiting)是多进程编程中的核心机制,指父进程…...
根据文件名称查询文件所在位置
在 Linux 中,根据文件名称查询文件所在位置主要通过命令行工具实现,以下是几种常用方法: --- ### **1. 使用 find 命令(最灵活)** find 命令可以递归搜索指定目录下的文件,支持按名称、类型、时间等条件过…...
六十天前端强化训练之第二十五天之组件生命周期大师级详解(Vue3 Composition API 版)
欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 一、生命周期核心知识 1.1 生命周期全景图 1.2 生命周期钩子详解 1.2.1 初始化阶段 1.2.2 挂载阶段 1.2.3 更新阶段 1.2.4 卸载阶段 1.3 生命周期执行顺序 1.4 父子组…...
Pytorch使用手册(专题五十)—自定义运算符
1. PyTorch 自定义运算符 PyTorch 提供了一个庞大的运算符库,这些运算符可以对张量进行操作(例如 torch.add、torch.sum 等)。然而,您可能希望向 PyTorch 引入一个新的自定义操作,并使其能够与诸如 torch.compile、autograd 和 torch.vmap 等子系统协同工作。为此,您必须…...
springboot整合mybatis-plus(保姆教学) 及搭建项目
一、Spring整合MyBatis (1)将MyBatis的DataSource交给Spring IoC容器创建并管理,使用第三方数据库连接池(Druid,C3P0等)代替MyBatis内置的数据库连接池 (2)将MyBatis的SqlSessionFactory交给Spring IoC容器创建并管理,使用spring-mybatis整…...
VSCode创建VUE项目(三)使用axios调用后台服务
1. 安装axios,执行命令 npm install axios 2. 在 main.ts 中引入并全局挂载 Axios 实例 修改后的 代码(也可以单独建一个页面处理Axios相关信息等,然后全局进行挂载) import { createApp } from vue import App from ./App.vue import rou…...
JVM常用垃圾回收器
Serial 和Serial Old收集器 Serial 系列的垃圾收集器采用了简单高效、资源消耗最少、单线程收集的设计思路。 简单高效:由于硬件资源有限,垃圾回收器需要设计得简单高效,以减少系统资源的占用。Serial 系列的垃圾收集器实现简单,…...
