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

Java8 HashMap高低位拆分扩容,核心逻辑一次性说清

一、Jdk71、扩容死锁分析死锁问题核心在于多线程扩容导致形成的链表环void transfer(Entry[] newTable, boolean rehash) { int newCapacity newTable.length; for (EntryK,V e : table) { while(null ! e) { //第一行 EntryK,V next e.next; if (rehash) { e.hash null e.key ? 0 : hash(e.key); } //第二行 int i indexFor(e.hash, newCapacity); //第三行 e.next newTable[i]; //第四行 newTable[i] e; //第五行 e next; } } }⚠️多线程扩容✔️假设有两个线程 T1 和 T2 同时检测到需要扩容它们都会创建新的数组并尝试迁移旧数组的元素。✔️由于没有同步控制两个线程会同时执行transfer()操作操作同一份链表数据导致指针错乱形成环形链表。二、Jdk81、实现原理Java8 HashMap扩容跳过了Jdk7扩容的坑对源码进行了优化采用高低位拆分转移方式避免了链表环的产生1.1、扩容前1.2、扩容后2、扩容方法resize数组的初始化和扩容都是通过调用resize方法完成的final NodeK,V[] resize() { // 扩容前的数组 NodeK,V[] oldTab table; // 扩容前的数组的大小和阈值 int oldCap (oldTab null) ? 0 : oldTab.length; int oldThr threshold; // 预定义新数组的大小和阈值 int newCap, newThr 0; if (oldCap 0) { // 超过最大值就不再扩容了 if (oldCap MAXIMUM_CAPACITY) { threshold Integer.MAX_VALUE; return oldTab; } // 扩大容量为当前容量的两倍但不能超过 MAXIMUM_CAPACITY else if ((newCap oldCap 1) MAXIMUM_CAPACITY oldCap DEFAULT_INITIAL_CAPACITY) newThr oldThr 1; // double threshold } // 当前数组没有数据使用初始化的值 else if (oldThr 0) // initial capacity was placed in threshold newCap oldThr; else { // zero initial threshold signifies using defaults // 如果初始化的值为 0则使用默认的初始化容量默认值为16 newCap DEFAULT_INITIAL_CAPACITY; newThr (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); } // 如果新的容量等于 0 if (newThr 0) { float ft (float)newCap * loadFactor; newThr (newCap MAXIMUM_CAPACITY ft (float)MAXIMUM_CAPACITY ? (int)ft : Integer.MAX_VALUE); } threshold newThr; SuppressWarnings({rawtypes,unchecked}) NodeK,V[] newTab (NodeK,V[])new Node[newCap]; // 开始扩容将新的容量赋值给 table table newTab; // 原数据不为空将原数据复制到新 table 中 if (oldTab ! null) { // 根据容量循环数组复制非空元素到新 table for (int j 0; j oldCap; j) { NodeK,V e; if ((e oldTab[j]) ! null) { oldTab[j] null; // 如果链表只有一个则进行直接赋值 if (e.next null) newTab[e.hash (newCap - 1)] e; else if (e instanceof TreeNode) // 红黑树相关的操作 ((TreeNodeK,V)e).split(this, newTab, j, oldCap); else { // preserve order // 链表复制JDK 1.8 扩容优化部分 NodeK,V loHead null, loTail null; NodeK,V hiHead null, hiTail null; NodeK,V next; do { next e.next; // 原位置原索引 if ((e.hash oldCap) 0) { // hash 值的 oldCap 位为 0 → 保持在原位置 j if (loTail null) // 记录低位链表的头 loHead e; else // 链接到前一个节点 loTail.next e; // 更新尾节点 loTail e; } // hash 值的 oldCap 位为 1 → 移动到 j oldCap else { if (hiTail null) // 记录高位链表的头 hiHead e; else // 链接到前一个节点 hiTail.next e; // 更新尾节点 hiTail e; } } while ((e next) ! null); // 断开低位链表的尾部 if (loTail ! null) { loTail.next null; newTab[j] loHead; } // 断开高位链表的尾部 if (hiTail ! null) { hiTail.next null; newTab[j oldCap] hiHead; } } } } } return newTab; }3、高低位扩容示例从容量 16 扩容到 3216132// 假设条件 oldCap 16 0b10000 newCap 32 0b100000 // 旧数组索引 5 处有一条链表 oldTab[5] → A(hash37) → B(hash53) → C(hash21) → D(hash69) → null步骤 1计算每个节点的 hash oldCap节点 A: hash 37 0b100101 37 16 0b100101 0b010000 0 → 低位 节点 B: hash 53 0b110101 53 16 0b110101 0b010000 16 ≠ 0 → 高位 节点 C: hash 21 0b010101 21 16 0b010101 0b010000 16 ≠ 0 → 高位 节点 D: hash 69 0b1000101 69 16 0b1000101 0b010000 0 → 低位步骤 2拆分链表原始链表 index 5: A(37) → B(53) → C(21) → D(69) → null 拆分后的两条链表 低位链表loHead: A(37) → C(69) → null 高位链表hiHead: B(53) → D(21) → null步骤 3安装到新数组新数组容量 32 index 5: A(37) → C(69) → null ← 低位链表 index (51621): B(53) → D(21) → null ← 高位链表⚠️高低位扩容的核心✔️判断条件(e.hash oldCap) 0✔️低位链表保持在原位置 j✔️高位链表移动到新位置 j oldCap✔️不需要重新计算 hash✔️链表被拆分成两条减少冲突✔️保持原有节点的相对顺序4、索引计算方法4.1、举个栗子package com.nl; public class HashMapDemo { public static void main(String[] args) { String test test1234678; System.out.println(计算容量为16的索引:((16-1) hash(test))); // 为0扩容后再原位置存放 System.out.println(容量为32的与运算值(test.hashCode() 32)); System.out.println(计算容量为32的索引:((32-1) hash(test))); // 不为0扩容后重新计算索引 System.out.println(容量为64的与运算值(test.hashCode() 64)); System.out.println(计算容量为64的索引:((64-1) hash(test))); } /** * 源码生成hashCode的方法 * param key * return */ static int hash(Object key) { int h; return (key null) ? 0 : (h key.hashCode()) ^ (h 16); } }4.2、输出计算容量为16的索引:8 容量为32的与运算值0 计算容量为32的索引:8 容量为64的与运算值64 计算容量为64的索引:40⚠️注意✔️容量为32的与运算值为0时扩容后索引不变✔️容量为64的与运算值为64时扩容后索引改变

相关文章:

Java8 HashMap高低位拆分扩容,核心逻辑一次性说清

一、Jdk7 1、扩容死锁分析 死锁问题核心在于多线程扩容导致形成的链表环 void transfer(Entry[] newTable, boolean rehash) {int newCapacity newTable.length;for (Entry<K,V> e : table) {while(null ! e) {//第一行Entry<K,V> next e.next;if (rehash) {e…...

功率波动平抑:从算法到并网标准验证

平抑功率波动&#xff0c;一分钟功率波动和十分钟功率波动 1、1min和10min满足国家并网标准 2、先用滑动平均算法或卡尔曼滤波算法进行平抑 3、求解平抑后是否满足国家并网标准 4、程序注释很详细。 有步骤的在电力系统中&#xff0c;确保功率稳定输出至关重要&#xff0c;而平…...

信息化建设-核心系统实施方法论

4.2 核心系统实施方法论4.2.1 核心系统实施的理论定位核心系统实施是企业信息化建设从规划走向现实的关键一步&#xff0c;其理论任务是将选定的软件产品通过科学的实施方法&#xff0c;成功部署到企业环境中&#xff0c;实现预期的业务价值。无论是采购成熟软件还是自研开发&a…...

信息化建设-实施路径规划与投资预算

3.5 实施路径规划与投资预算3.5.1 实施路径规划的理论价值实施路径规划是信息化建设从蓝图到现实的“施工计划”&#xff0c;其理论任务是将整体架构设计分解为可执行、可管理、可验证的阶段任务&#xff0c;明确每个阶段的目标、范围、时间、资源和预算&#xff0c;确保信息化…...

信息化整体架构设计与技术选型

规划篇——蓝图设计与路径规划3.4 整体架构设计与技术选型3.4.1 整体架构设计的理论价值整体架构设计是信息化建设的“施工蓝图”&#xff0c;其理论任务是将业务需求和功能需求转化为可落地实施的技术方案&#xff0c;明确系统的组成部分、相互关系、技术标准和演进路径。如果…...

罗姆最新碳化硅模块已登陆线上平台

基于第四代技术的模块支持小型化并减少设计工作量。罗姆&#xff08;Rohm&#xff09;已开始通过 DigiKey 等分销商在线销售新的碳化硅&#xff08;SiC&#xff09;模压模块&#xff0c;包括 TRCDRIVE pack、HSDIP20 和 DOT-247。TRCDRIVE pack 是一款 2-in-1 碳化硅模压模块&a…...

攻克三线仿真问题:经验与分享

三线仿真问题解决在开发过程中&#xff0c;三线仿真问题着实让人头疼了一阵。最近总算是把这个难题给啃下来了&#xff0c;今天就来跟大家唠唠我解决这个问题的全过程&#xff0c;希望能给遇到类似情况的小伙伴们一些启发。 问题初现 起初&#xff0c;三线仿真出现异常时&#…...

2026更新版!9个AI论文平台测评:专科生毕业论文写作与格式规范全攻略

随着人工智能技术的快速发展&#xff0c;AI写作工具在学术领域的应用越来越广泛。对于专科生而言&#xff0c;撰写毕业论文不仅是学业的重要环节&#xff0c;更是对综合能力的一次全面检验。然而&#xff0c;面对繁重的写作任务、复杂的格式规范以及内容质量把控难题&#xff0…...

2026必备!AI论文写作软件 千笔ai写作 VS 万方智搜AI,继续教育写作者首选

随着人工智能技术的迅猛迭代与普及&#xff0c;AI辅助写作工具已逐步渗透到高校学术写作场景中&#xff0c;成为专科生、本科生、研究生完成毕业论文不可或缺的辅助手段。越来越多面临毕业论文压力的学生&#xff0c;开始依赖各类AI工具简化写作流程、提升创作效率。但与此同时…...

学长亲荐 10个降AIGC软件:开源免费测评,帮你高效降AI率

在学术写作中&#xff0c;AI生成内容的普及带来了新的挑战——如何有效降低AIGC率&#xff0c;同时保持论文的原创性和逻辑性。近年来&#xff0c;越来越多的学生和研究人员开始依赖专业的AI降重工具&#xff0c;这些工具不仅能精准识别并去除AI痕迹&#xff0c;还能在不破坏原…...

学长亲荐!全场景通用AI论文神器 —— 千笔

你是否曾为论文选题发愁&#xff0c;反复修改却仍不满意&#xff1f;是否在查重和格式上耗费大量时间&#xff0c;却收效甚微&#xff1f;论文写作的每一个环节都像一座难以逾越的高山&#xff0c;让人倍感压力。而今&#xff0c;一款真正能解决这些难题的AI工具——千笔AI&…...

AI 数学的秘密花园:24.噪声调度(逐层揭开面纱,像剥洋葱一样,超级有节奏感)

第24章.噪声调度(逐层揭开面纱,像剥洋葱一样,超级有节奏感) 咱们的AI数学秘密花园又翻到第24章啦~上一章咱们刚挑好了最公平的高斯“洗衣粉”,现在轮到怎么用它来“洗照片”了!这环节超级有节奏感,名字就叫噪声调度(Noise Scheduling)。 简单说,就是不能一把把照片…...

ERP+PDA库存管理省时省力的庖丁解牛

ERPPDA 库存管理组合&#xff0c;是跨境电商卖家从“人治”迈向“数治”的关键一跃。 如果说 ERP 是仓库的“大脑”&#xff08;负责数据、逻辑、决策&#xff09;&#xff0c;那么 PDA&#xff08;手持数据终端&#xff09;就是仓库的“手脚”和“眼睛”&#xff08;负责执行、…...

ERP为跨境电商卖家身打造的全链路解决方案的庖丁解牛

跨境电商卖家面临的核心挑战是**“全球卖、本地化运营、合规化经营、精细化核算”**。单一工具&#xff08;如打单软件、库存表格&#xff09;已无法支撑复杂业务。 全链路 ERP 解决方案的本质&#xff0c;是将选品、采购、刊登、订单、仓储、物流、财务、客服、合规九大环节&a…...

YOLOv11涨点改进| TGRS 2026 |独家创新首发、特征融合改进篇| 引入CIFusion 通道交互融合模块,通过跨特征交互机制强化目标区域响应,适合多模态融合目标检测,小目标检测高效涨点

一、本文介绍 🔥这篇论文作者使用YOLOv11模型发SCI一区!喜提TGRS 2026顶刊!做遥感小目标检测任务。 本文给大家介绍利用 CIFusion 通道交互融合模块 改进YOLOv11网络模型,从而提高目标检测性能。CIF 通过对 RGB 与红外特征进行通道级自适应交互,根据全局上下文动态分配…...

YOLOv11涨点改进| TGRS 2026 |全网创新首发、Conv卷积改进篇 | 引入SFEM空间-频率特征增强模块,同时建模空间域和频域信息,助力YOLOv11遥感小目标检测,小目标分割高效涨点

一、本文介绍 🔥这篇论文作者使用YOLOv11模型发SCI一区!喜提TGRS 2026顶刊!做遥感小目标检测任务。 本文给大家介绍利用SFEM空间-频率特征增强模块改进YOLOv11网络模型,SFEM 是一种面向 RGB 分支的空间–频域特征增强模块,主要作用是提升复杂场景下 RGB 特征的表达能力…...

YOLO26改进89:全网首发--c3k2模块添加LEGM模块

论文介绍 DCMPNet(Depth Information Assisted Collaborative Mutual Promotion Network)是一个面向单图像去雾任务的深度学习模型,全称为 “深度信息辅助的协同互促网络”,由开发者 zhoushen1 开源在 GitHub 上,核心目标是利用深度信息提升单图像去雾的效果。 核心定位 针…...

YOLO26改进88:全网首发--c3k2模块添加C3k2_EfficientVIM_CGLU组合创新模块

论文介绍 神经网络在资源受限环境中的部署 针对资源受限环境下的神经网络部署,先前研究通过结合卷积与注意力机制构建轻量级架构,分别用于捕捉局部与全局依赖关系。近期,状态空间模型(SSM)因其在token数量上具备线性计算复杂度的优势,成为实现全局交互的高效操作。 Eff…...

【信息科学与工程学】【财务管理】 第十八篇 企业利润设计

企业利润设计模型表第1条字段内容编号​P-L1-0001类别​综合优化模型领域​管理会计与运营管理信息差/认知差/人性差​信息差&#xff1a;传统成本核算&#xff08;如完全成本法&#xff09;无法准确将间接费用&#xff08;如工程支持、质检&#xff09;追溯到消耗这些资源的具…...

6 纠偏调适:承认跑偏,比硬撑更需要勇气

6 纠偏调适&#xff1a;承认跑偏&#xff0c;比硬撑更需要勇气 1核对分析 Step1:核对信息 Step2:问题排序 Step3:分析原因 2纠偏调适 1.纠偏的策略 2.调适的策略...

职场话术优化器,输入沟通场景,自动生成温和坚定表达,减少冲突,提高情商。

职场话术优化器 - 高情商沟通助手一、实际应用场景描述场景&#xff1a;小李是一名产品经理&#xff0c;需要在周会上向技术团队反馈"需求延期"的问题。他原本想说&#xff1a;"你们怎么又延期了&#xff1f;这样下去项目肯定完不成&#xff01;" 但担心这…...

为什么中国高考考外语,美英法不考汉语?全民强制学英语合理吗?

为什么中国高考考外语&#xff0c;美英法不考汉语&#xff1f;全民强制学英语合理吗&#xff1f;有一个问题&#xff0c;相信很多人都曾心生疑惑、难以释怀&#xff1a;全球以中文为母语的人数约15亿&#xff0c;远超以英语为母语的3.9亿&#xff0c;为何中国高考要将外语列为必…...

自检的邮件服务器发送的邮件可能被拒收-----伪造邮件地址

这个问题触及了邮件系统的一个核心机制&#xff01;答案是&#xff1a;技术上完全可以&#xff0c;但这种行为通常被称为"邮件伪造"&#xff08;Email Spoofing&#xff09;&#xff0c;而且现代邮件系统有完善的防护机制来阻止这种行为。让我详细解释一下这背后的原…...

地表水源热泵系统建模与粒子群算法优化探究

matlab代码 从水源热泵机组角度对地表水源热泵系统建模&#xff0c;并采用粒子群算法求解热泵机组每小时最佳制冷量和制热量。 在能源日益紧张的当下&#xff0c;高效利用可再生能源的技术愈发受到关注&#xff0c;地表水源热泵系统便是其中之一。今天咱们就从水源热泵机组的角…...

QT编程(11):Qt 文本高亮实现代码编辑器

一、功能概述与核心原理 本次基于Qt Widgets实现一款简易代码编辑器&#xff0c;核心实现自定义语法文本高亮、基础代码编辑、行号显示、关键字/注释/字符串区分高亮四大核心功能&#xff0c;适配C/C基础语法高亮规则&#xff0c;可轻松拓展到Python、Java等其他语言。 核心技术…...

php方案 PHP 实现协程调度器

两个方向&#xff1a;用 Swoole&#xff08;生产&#xff09;或纯 PHP Generator 手写&#xff08;理解原理&#xff09;。---方向一&#xff1a;Swoole 协程&#xff08;生产首选&#xff09;docker run --rm phpswoole/swoole php coroutine.php<?php// coroutine.phpuse…...

php方案 PHP 实现分布式任务调度

一、分布式任务调度&#xff08;类 XXL-Job&#xff09;composer require swoole/ide-helper predis/predis架构&#xff1a;[调度中心 Scheduler] → Redis → [执行器节点 Worker x N]↑ ↓定时触发 执行任务上报结果调度…...

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理

【Java 开发日记】我们来说一下无锁队列 Disruptor 的原理 今天来聊聊 Java 并发领域里一个“神器”级别的组件 —— LMAX Disruptor。它被誉为“高性能无锁队列”&#xff0c;在金融交易系统、日志处理、高吞吐消息中间件等领域广泛使用。LMAX 交易所曾用它实现单线程处理 60…...

Java中的char、String、StringBuilder与StringBuffer 深度详解

Java 中的 char、String、StringBuilder 与 StringBuffer 深度详解 &#xff08;从底层原理到最佳实践&#xff0c;2026 最新版&#xff09; 这四个类型是 Java 字符串处理的基石&#xff0c;几乎每天都会用到。掌握它们&#xff0c;能让你写出更高效、更安全的代码。 1. cha…...

锁相环PLL:设计与进阶之路

锁相环PLL pll设计与进阶在电子工程的世界里&#xff0c;锁相环&#xff08;PLL, Phase - Locked Loop&#xff09;就像是一个神秘而强大的魔法师&#xff0c;默默地在各种电路系统中发挥着关键作用。无论是在通信领域&#xff0c;确保信号的稳定传输&#xff1b;还是在时钟生成…...