HashMap底层数据结构及其增put删remove查get方法的代码实现原理

简介: HashMap 是基于数组 + 链表 + 红黑树实现的高效键值对存储结构。默认初始容量为16,负载因子为0.75。当存储元素超过容量 * 负载因子时,会进行扩容。HashMap 使用哈希算法计算键的索引位置,通过链表或红黑树解决哈希冲突,确保高效存取。插入、获取和删除操作的时间复杂度接近 O(1)。

PS:由于文档是我在本地编写好之后再复制过来的,有些文本格式没能完整的体现,故提供下述图片,供大家阅览,以便有更好的阅读体验:
image.png

1.HashMap底层数据结构是数组+链表(jdk1.7头插法<扩容时链表逆序可能会导致环形链表的问题出现> jdk1.8尾插法)+红黑树(jdk1.8).
2.HashMap中数组的容量默认为16,负载因子默认为0.75,当数组的0-15个下标里有16×0.75=12个被使用时,且HashMap中存储的元素总个数大于64时,则发生扩容操作,数组的容量扩大为原来的2n.
3.负载因子代表数组中存储数据密度的大小:负载因子越大,数组单位容量内存储的数据越多,不同元素之间(key不同,但计算得到的数组下标相同)越容易发生碰撞(哈希碰撞);反之,则单位容量内存储的数据越少,越不易发生碰撞.
4.put(key,value)时的处理逻辑:
(1)hash(key) = (key==NULL)?0:(h=key.hashCode())^(h>>>16),即取key的原始哈希码的高低16位进行异或位运算,计算出一个经高低位混合后高低位分布更加均匀的新哈希码,再用该新哈希码和数组容量减一做与位运算(hash(key)&(2^n-1))得出要存放的数组下标[当HashMap的容量是2的n次幂时,(2^n-1)的二进制就是11111*111全1的形式,这样与hash(key)进行与的位运算时,能够充分的散列,使得添加的元素均匀分布到HashMap的每个位置上,减少hash碰撞],可以一定程度降低根据不同元素计算得出相同数组下标(哈希碰撞)的概率;
(2)得出的数组下标里已经存放有数据元素,则根据key的值遍历比较该下标下的链表或红黑树,如果遇到相同key,则更新key对应的value值后返回(return);若遍历链表后未遇到相同的key,则在链表(jdk1.7头部 jdk1.8尾部)或红黑树合适位置(可能触发红黑树的左旋右旋或颜色改变),插入新的(key,value)键值对元素(插入值时统计存储的总元素个数的变量值会加一) ;
(3)某链表插入新的键值对后,可能导致该链表的长度大于等于8,若此时数组存储的总元素个数大于等于64,则将链表转为红黑树(保证最好最坏情况下时间复杂度为以2为底总元素个数n的对数级别,以提高增删查处理性能);
(4)链表插入新值后,也可能会触发数组扩容操作
5.get(key)时的处理逻辑:同put(key,value)的步骤(1),会根据key值计算得出数组下标,然后用key值遍历比较该数组下标下的链表或或红黑树,找到相同key对应的value值并返回,否则,返回null;
6.remove(key)时的处理逻辑:同get(key)和put(key,value)的步骤(1),会先根据key找到要删除元素所在位置,然后进行删除操作;

目录
相关文章
|
11月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
475 1
|
12月前
|
索引
HashMap的put方法的具体流程?
1. 判断键值对数组table[i]是否为空或为null,否则执行resize()进行扩容; 2. 根据键值key计算hash值得到插入的数组索引i,如果table[i]==null,直接新建节点添加,转向 ⑥,如果table[i]不为空,转向③; 3. 判断table[i]的首个元素是否和key一样,如果相同直接覆盖value,否则转向④,这里的相同指的 是hashCode以及equals; 4. 判断table[i] 是否为treeNode,即table[i] 是否是红黑树,如果是红黑树,则直接在树中插入键值 对,否则转向5; 5. 遍历table[i],判断链表长度是否大于8,大于8的
|
存储 缓存 Java
HashMap源码剖析-put流程
更好地掌握 `HashMap` 的内部实现原理,提高编写高效代码的能力。掌握这些原理不仅有助于优化性能,还可以帮助解决实际开发中的问题。
476 13
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
558 1
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
186 1
|
Java
让星星⭐月亮告诉你,HashMap中保证红黑树根节点一定是对应链表头节点moveRootToFront()方法源码解读
当红黑树的根节点不是其对应链表的头节点时,通过调整指针的方式将其移动至链表头部。具体步骤包括:从链表中移除根节点,更新根节点及其前后节点的指针,确保根节点成为新的头节点,并保持链表结构的完整性。此过程在Java的`HashMap$TreeNode.moveRootToFront()`方法中实现,确保了高效的数据访问与管理。
164 2
|
Java 索引
让星星⭐月亮告诉你,HashMap之往红黑树添加元素-putTreeVal方法源码解读
本文详细解析了Java `HashMap` 中 `putTreeVal` 方法的源码,该方法用于在红黑树中添加元素。当数组索引位置已存在红黑树类型的元素时,会调用此方法。具体步骤包括:从根节点开始遍历红黑树,找到合适位置插入新元素,调整节点指针,保持红黑树平衡,并确保根节点是链表头节点。通过源码解析,帮助读者深入理解 `HashMap` 的内部实现机制。
253 2
|
9月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
436 3
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
246 0
|
Java
IDEA debug HashMap源码的心得
IDEA debug HashMap源码的心得
264 0