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

Java 集合框架大师课:集合框架源码解剖室(五)

🔥Java 集合框架大师课:集合框架源码解剖室(五)

💣 警告:本章包含大量 裸码级硬核分析,建议搭配咖啡因饮料阅读!☕️


第一章 ArrayList 的扩容玄学

1.1 动态扩容核心代码大卸八块

// 祖师爷の扩容魔法 ✨
private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;// 1.5倍增长公式(暗藏数学之美)int newCapacity = oldCapacity + (oldCapacity >> 1); return elementData = Arrays.copyOf(elementData, newCapacity);
}

📌 灵魂拷问表

现象数学原理性能影响
初始容量102的倍数+2?🤔小数据集省内存
1.5倍增长斐波那契数列逼近 🌊平衡内存与扩容次数
Arrays.copyOf内存连续分配 📏超大数组扩容卡顿风险

1.2 扩容流程可视化

在这里插入图片描述


第二章 HashMap 的哈希战争

2.1 扰动函数の黑科技

static final int hash(Object key) {int h;// 让高位参与哈希运算,减少碰撞 💥return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

🎯 哈希碰撞处理方案对比

方案数据结构时间复杂度JDK版本
链表法单向链表 🚂O(n)<8
红黑树平衡二叉树 🌳O(logn)≥8
开放寻址线性探测 🔍O(1)~O(n)其他实现

2.2 树化阈值背后的博弈

// 链表转红黑树的临界点
static final int TREEIFY_THRESHOLD = 8;// 为什么是8?统计学の魔法 🎲
/*
* 理想哈希下链表长度出现8的概率:0.00000006
* 此时树化的收益超过维护成本
*/

第三章 LinkedList 的双向暗恋

3.1 节点结构解剖图

private static class Node<E> {E item;          // 当前元素 🎁Node<E> next;    // 下个节点 👉Node<E> prev;    // 上个节点 👈
}

📊 增删操作性能真相

操作ArrayListLinkedList真相大白 😏
头部插入O(n)O(1)LinkedList胜
随机删除O(n)O(1)但需要先遍历找节点!😱
尾部追加O(1)O(1)平手 👯

3.2 迭代器陷阱演示

LinkedList<Integer> list = new LinkedList<>();
list.addAll(Arrays.asList(1,3,5,7,9));// 错误示范:用for循环随机访问
for(int i=0; i<list.size(); i++){list.get(i); // O(n^2) 警告!💣
}// 正确姿势:迭代器访问
Iterator<Integer> it = list.iterator();
while(it.hasNext()){it.next(); // O(n) 丝滑访问 🛷
}

第四章 ConcurrentHashMap 的线程安全秘籍

4.1 📌 锁机制对比表

版本数据结构锁粒度吞吐量提升
JDK7Segment 数组16个独立分区 🔒4~6倍
JDK8Node+CAS单个链表头 🔓10倍+
JDK19协程+无锁无锁访问 🚀实验阶段

4.2 size() 方法の统计学魔术

// 高并发下的size计算策略
public int size() {long n = sumCount();return ((n < 0L) ? 0 : (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)n);
}// 分片计数减少竞争 🎯
final long sumCount() {CounterCell[] as = counterCells; long sum = baseCount;if (as != null) {for (CounterCell a : as)if (a != null)sum += a.value;}return sum;
}

4.3 putVal() 方法源码拆解

final V putVal(K key, V value, boolean onlyIfAbsent) {// 哈希扰动加强版 🌪️int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh;if (tab == null || (n = tab.length) == 0)tab = initTable(); // 延迟初始化else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {if (casTabAt(tab, i, null, new Node<>(hash, key, value)))break; // CAS 无锁插入成功!}else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f); // 协助扩容else {// 真正的锁竞争区 💥synchronized (f) {if (tabAt(tab, i) == f) {// 链表/红黑树插入逻辑...}}}}addCount(1L, binCount);return null;
}

🎯 关键操作流程图

在这里插入图片描述


🔥 性能调优黄金法则

// ArrayList 最佳实践
List<String> list = new ArrayList<>(100_0000); // 预分配容量 🚀// HashMap 防坑指南
Map<String,Object> map = new HashMap<>(32, 0.75f); // 控制负载因子 ⚖️// LinkedList 使用禁区
if(需要随机访问) {throw new IllegalArgumentException("别用我!"); 💣
}

第五章 LinkedHashMap 的时空穿梭术

5.1 双向链表结构大曝光

// 继承自 HashMap.Node 的超级节点 🦸
static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after; // 时空隧道入口 🕳️Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}
}// 维护访问顺序的核心代码 🔗
void afterNodeAccess(Node<K,V> e) {Entry<K,V> last;if (accessOrder && (last = tail) != e) {// 把最近访问的节点移动到链表尾部Entry<K,V> p = (Entry<K,V>)e, b = p.before, a = p.after;p.after = null;if (b == null)head = a;elseb.after = a;if (a != null)a.before = b;elselast = b;if (last == null)head = p;else {p.before = last;last.after = p;}tail = p;++modCount;}
}

5.2 LRU 缓存实现原理

// 实现简易 LRU 缓存 🗂️
public class LRUCache<K,V> extends LinkedHashMap<K,V> {private final int maxCapacity;public LRUCache(int maxCapacity) {super(maxCapacity, 0.75f, true);this.maxCapacity = maxCapacity;}@Overrideprotected boolean removeEldestEntry(Map.Entry<K,V> eldest) {return size() > maxCapacity; // 自动淘汰最旧元素 🗑️}
}// 使用示例:
LRUCache<String, User> cache = new LRUCache<>(1000);
cache.put("user_9527", user); // 插入新数据
cache.get("user_1234");       // 访问数据会提升新鲜度

第六章 PriorityQueue 的堆排序魔法

6.1 最小堆实现原理

// 优先队列的骨架数组结构 🦴
transient Object[] queue; // 元素插入时的上浮操作 🌊
private void siftUp(int k, E x) {if (comparator != null)siftUpUsingComparator(k, x);elsesiftUpComparable(k, x);
}private void siftUpComparable(int k, E x) {Comparable<? super E> key = (Comparable<? super E>) x;while (k > 0) {int parent = (k - 1) >>> 1; // 找父节点位置Object e = queue[parent];if (key.compareTo((E) e) >= 0)break;queue[k] = e; // 父节点下沉k = parent;}queue[k] = key;
}

📊 堆操作复杂度表

操作时间复杂度原理说明
插入元素O(logn)上浮操作调整堆结构 🌊
取出队首O(logn)下沉操作重建堆结构 ⚓
查看队首O(1)直接返回堆顶元素 🏔️
批量建堆O(n)Floyd 算法优化 🚀

6.2 堆结构可视化

在这里插入图片描述


🛠️ 手撕源码挑战赛

挑战一:ConcurrentHashMap 扩容触发器

// 找出触发扩容的隐藏条件
private final void addCount(long x, int check) {// 当 counterCells 不为空时...if (check >= 0) {Node<K,V>[] tab, nt; int n, sc;while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&(n = tab.length) < MAXIMUM_CAPACITY) {// 神秘扩容信号 🚨int rs = resizeStamp(n);if (sc < 0) {if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||transferIndex <= 0)break;if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))transfer(tab, nt);}// 尝试发起扩容的线程会走到这里 💪else if (U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2))transfer(tab, null);s = sumCount();}}
}

挑战二:PriorityQueue 堆排序缺陷

// 危险操作:直接修改队列元素
PriorityQueue<Student> queue = new PriorityQueue<>();
queue.add(new Student("Alice", 90));
queue.add(new Student("Bob", 80));// 作死修改分数导致堆结构破坏 💣
queue.peek().score = 100; 
System.out.println(queue.poll()); // 输出结果可能不符合预期!// 正确做法:删除后重新插入
Student s = queue.poll();
s.score = 100;
queue.offer(s);

🧘♂️ 下期预告:《集合框架的暗黑料理——弱引用与幽灵队列》👻

// 彩蛋代码:HashMap 的隐藏迭代器
final class KeyIterator extends HashIterator implements Iterator<K>, Spliterator<K> {public final K next() { return nextNode().key; }
}
// 快速失败(fail-fast)机制的实现秘密 🔍

🌟 终极领悟 :读源码就像破案,每个设计都是权衡的艺术!下次面试被问HashMap原理时,请优雅地甩出红黑树阈值计算公式 🌈

// 彩蛋:HashMap 树化阈值计算公式
static final int TREEIFY_THRESHOLD = 8;
// 为什么是8?因为 log8 = 3, 在O(logn)和O(n)之间找到平衡点 ⚖️

相关文章:

Java 集合框架大师课:集合框架源码解剖室(五)

&#x1f525;Java 集合框架大师课&#xff1a;集合框架源码解剖室&#xff08;五&#xff09; &#x1f4a3; 警告&#xff1a;本章包含大量 裸码级硬核分析&#xff0c;建议搭配咖啡因饮料阅读&#xff01;☕️ 第一章 ArrayList 的扩容玄学 1.1 动态扩容核心代码大卸八块 …...

llamafactory 微调教程

文章目录 llamlafactory微调deepseekr1-0.5b1.1 说明1.2 搭建环境创建GPU实例连接实例部署llama_factory创建隧道&#xff0c;配置端口转发访问llama_factory 1.3 微调大模型从huggingface上下载基座模型查看模型是否下载成功准备数据集微调评估微调效果导出合并后的模型 释放实…...

代码随想录|二叉树|04二叉树的统一迭代法

一刷我这里放了。。。 代码随想录...

【教学类-43-25】20240311 数独3宫格的所有可能(图片版 12套样式,空1格-空8格,每套510张,共6120小图)

背景需求&#xff1a; 有一位客户买3宫格所有可能&#xff08;WORD表格版&#xff09; 【教学类-43-25】20241203 数独3宫格的所有可能-使用模版替换-用时少报错少&#xff08;12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120小图&#xff09;_数独三…...

Manus AI:多语言手写识别的技术革命与未来图景

摘要&#xff1a;在全球化浪潮下&#xff0c;跨语言沟通的需求日益迫切&#xff0c;但手写文字的多样性却成为技术突破的难点。Manus AI凭借其多语言手写识别技术&#xff0c;将潦草笔迹转化为精准数字文本&#xff0c;覆盖全球超百种语言。本文从技术原理、应用场景、行业价值…...

领域驱动设计(DDD)是什么?

领域驱动设计&#xff08;DDD&#xff09;是什么&#xff1f; 在软件开发的世界里&#xff0c;我们总在寻找那把打开业务之门的钥匙。有人迷恋MVC的简洁&#xff0c;有人追逐微服务的潮流&#xff0c;而DDD&#xff08;领域驱动设计&#xff09;则像一位沉默的智者&#xff0c;…...

JavaScript 模块 vs C# 类:封装逻辑的两种哲学

引言 在现代软件开发中&#xff0c;模块化和面向对象设计是代码组织的核心课题。本文通过对比 JavaScript 模块&#xff08;ES6 Module&#xff09;与 C# 类&#xff08;Class&#xff09;的实现方式&#xff0c;探讨两种语言在封装逻辑时的不同哲学&#xff0c;并给出实际应用…...

2.2 企业级ESLint/Prettier规则定制

文章目录 1. 为什么需要企业级代码规范2. 工具选型对比3. 完整配置流程3.1 项目初始化3.2 ESLint深度配置3.3 Prettier精细配置3.4 解决规则冲突4. 高级定制方案4.1 自定义ESLint规则4.2 扩展Prettier插件5. 团队协作策略5.1 配置共享方案5.2 版本控制策略6. CI/CD集成7. 常见问…...

Linux学习(十五)(故障排除(ICMP,Ping,Traceroute,网络统计,数据包分析))

故障排除是任何 Linux 用户或管理员的基本技能。这涉及识别和解决 Linux 系统中的问题。这些问题的范围包括常见的系统错误、硬件或软件问题、网络连接问题以及系统资源的管理。Linux 中的故障排除过程通常涉及使用命令行工具、检查系统和应用程序日志文件、了解系统进程&#…...

DeepIn Wps 字体缺失问题

系统缺失字体 Symbol 、Wingdings 、Wingdings2、Wingdings3、MT—extra 字体问题 问了下DeepSeek 在应用商店安装或者在windows 里面找 装了一个GB-18030 还是不行 在windows里面复制了缺失的字体 将字体复制到DeepIn 的字体目录&#xff08;Ubuntu 应该也是这个目录&am…...

(二分 数学推导 统计公平数对的数目)leetcode 2563

数学推导&#xff1a; lower < nums[i] nums[j] < upper且0 < i < j < n 则lower-nums[j]<nums[i]<upper-nums[j] 找到这个范围的nums[i]的个数就是我们要的值 所以枚举j 在0--&#xff08;j-1&#xff09;的范围内 找到第一个大于等于lower-nums[j]…...

临界比例法PID调整-附带pidtune工具和GA算法

代码已上传&#xff1a;计算机控制系统PID参数整定法资源-CSDN文库 1背景 为了模拟PID参数整定&#xff0c;把教材上的案例进行分析。 1题目 单位闭环传递函数&#xff0c;开环传函G(s)1/((s1)(s2)), Ts0.1s, PID调整器输出后&#xff0c;接零阶保持器ZOH。 2 代码 PID含积…...

LabVIEW基于双通道FFT共轭相乘的噪声抑制

对于双通道采集的含噪信号&#xff0c;通过FFT获取复数频谱后&#xff0c;对第二通道频谱取共轭并与第一通道频谱相乘&#xff0c;理论上可增强相关信号成分并抑制非相关噪声。此方法适用于通道间信号高度相关、噪声独立的场景&#xff08;如共模干扰抑制&#xff09;。以下为L…...

小程序SSL证书过期怎么办?

SSL证书就像小程序的“安全锁”&#xff0c;一旦过期&#xff0c;用户访问时会被提示“不安全”&#xff0c;轻则流失客户&#xff0c;重则数据泄露&#xff01;作为企业负责人&#xff0c;如何快速解决证书过期问题&#xff1f;又该如何避免再次踩坑&#xff1f;这篇指南给你答…...

ELK日志分析实战

ELK日志分析实战&#xff1a;从异常流量定位提权攻击 摘要&#xff1a;本文通过模拟真实攻防场景&#xff0c;结合ELK技术栈&#xff08;ElasticsearchLogstashKibana&#xff09;&#xff0c;演示如何从海量服务器日志中快速定位异常流量并追踪提权攻击行为。包含完整的日志收…...

阿里云操作系统控制台实战评测:提升云资源管理与监控效率

文章目录 前言产品介绍操作系统控制台体验阿里云操作系统开通 帮助与总结建议 前言 随着云计算和虚拟化技术的发展&#xff0c;操作系统控制台作为运维管理的核心工具之一&#xff0c;在现代IT环境中发挥着越来越重要的作用。它提供了一种更加直观、高效的方式来管理操作系统&…...

Docker构建启动jar包

Docker构建启动jar包 1、首先是把java服务打包成jar包 mvn clean install -Dmaven.skip.testtrue package -Pprod这个命令的意思是&#xff0c;跳过测试&#xff0c;打包prod环境。 2、编写Dockerfile文件 # 拉取jdk8作为基础镜像 FROM registry.supos.ai/library/openjdk:…...

微信小程序使用的SSL证书在哪里申请?

在数字化时代&#xff0c;微信小程序已成为众多企业和个人开发者触达用户的重要平台。然而&#xff0c;随着网络安全威胁的日益严峻&#xff0c;确保小程序数据传输的安全性显得尤为重要。SSL证书&#xff0c;作为加密通信的基石&#xff0c;是保障小程序安全不可或缺的一环。 …...

基于langchain+llama2的本地私有大语言模型实战

Langchain功能 LangChian 作为一个大语言模型&#xff08;LLM, Large Language Model&#xff09;开发框架&#xff0c;是 LLM 应用架构的重要一环。借助 LangChain&#xff0c;我们可以创建各种应用程序&#xff0c;包括聊天机器人和智能问答工具。 AI模型&#xff1a;包含各…...

如何使用postman来测试接口

一、postman的介绍与下载 可参考&#xff1a; https://blog.csdn.net/freeking101/article/details/80774271 二、api获取网站 阿里云API应用市场 地址&#xff1a;云市场_镜像市场_软件商店_建站软件_服务器软件_API接口_应用市场 - 阿里云 三、具体测试过程 可模拟浏览…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...