HashMap底层数据结构(数组+链表+红黑树)

article/2025/9/21 23:57:58

回顾一下HashMap的底层数据结构

HashMap底层实现JDK<=1.7数组+链表,JDK>=1.8数组+链表+红黑树;HashMap这一个类型底层涉及到3中数据类型,数组、链表、红黑树,其中查询速度最快的是数组,时间复杂度是O(1),链表数据量少的时候还行,数据量过大性能就一般了,它的时间复杂度是O(N),红黑树在数据量打的时候性能会比链表要好,他的时间复杂度是O(logn),这里在链表和红黑树这里性能对比其实在HashMap的扩容时,已经体现出来了,Hash值产生碰撞后,链表长度>8时会由链表转换为红黑树,而当红黑树的节点<6时,会由红黑树转换为链表,这就是二者的性能临界点。
之前有篇博客写过HashMap的源码导读,这里就不在解释了,详情

为什么使用数组?
速度:读、写,最快的是数组, 数组快是快,但是需要知道读、写的索引,时间复杂度是O(1),对于一般的插入、删除操作,涉及到数组元素的移动,平均时间复杂度这变为O(N),HashMap中数组的下标是通过KEY.hashCode()%数组长度得到的,但是这种方法会造成哈希碰撞,那么就有了链表这个玩意!

为什么使用链表?
这里就不过多解释了,简单说就是为了解决数据的KEY产生哈希碰撞后将原有的数组下标对应的值直接替换,那么这个时候为了解决这个问题就在产生哈希碰撞后,下标相同的KEY就会被串成链表结构,插是从头插,不是从尾,从头插时间复杂度为O(1),从尾插为O(N),这个链表是单向列表, 链表的新增,删除操作在查找到操作位置后,只需要处理节点间的引用即可,时间复杂度为O(1),但是查找操作则需要遍历链表中所有节点逐一比对,时间复杂度为O(N),这里的查询的时间复杂度为O(N)且遍历所有元素是原因数组变成链表是因为哈希碰撞的hashCode值都是一样的,那么对应的索引也是一样的,所有还要一个KEY取出来对比,所以也就有了遍历这么一说;这样的话链表过长性能会比较低,那么为了解决性能问题,JDK1.8后就引用了红黑树;

为什么使用红黑树?
这里也不过多解释了,简单说就是为了解决链表过长性能低的问题,红黑树是一种接近于平衡二叉树,但不是绝对平衡,逻辑上是个树形结构,是一个有序的结构,在每个节点上增加一个存储位,表示节点的颜色,可以是Red或者Black,通过对任何一条从根到叶子的路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其他路径长出两倍,而是接近平衡的,支持查找,插入,删除,其平均时间复杂度最坏为O(logn);这里解释一下(红黑树确保没有任何一条路径会比其他路径长出两倍)在这里插入图片描述
这里比如13–>17–>25–>27这条链路不会比13–>8–>1、13–>8–>11、13–>8–>1–>6、13–>17–>15、13–>17–>25–>22这些链路的路径长出两倍,因为他会自动平衡,也就是当任何一条链路的路径高出其他链路2倍是,这条链路就会自动平衡,但是如果put比较频繁,且会经常打破平衡的话,那么这条链路就会自动平衡,这时的性能就会很低,低于链表;这里平衡有两种方式,左旋、右旋
左旋:
在这里插入图片描述
以这个为模拟数据,现在我们来添加一个数据来打破平衡(红黑树确保没有任何一条路径会比其他路径长出两倍),现在最短的链路是50–>60,最长的是50–>40–>45–>47,现在这条最长的刚好是最短的两倍,那么这时要是再来一个49,这里49比50小,比40大,比45大,比47大,那么会挂在50–>40–>45–>47这条链路上,刚挂上去的结构是这样的,

在这里插入图片描述
嘿嘿,这个平衡就打破了,那么就会自动平衡,那么这种数据模型位移叫做左旋,左旋后的红黑树结构!
在这里插入图片描述
右旋则刚好相反!!!
这是一个可视化HashMap操作的工具

红黑 树有6个性质;

  1. 每个节点要么是红的要么是黑的
  2. 根节点是黑的
  3. 每个叶节点(叶节点指树尾端NL指针或NULL节点)都是黑的
  4. 如果一个节点是红的,那么他的两个子节点都是黑的
  5. 对于任何而言,其到节点树尾端NL指针的每条路径都包含相同数目的黑节点
  6. 所有的左节点都<=父节点,所有的右节点都>父节点

http://chatgpt.dhexx.cn/article/9mZoPCB6.shtml

相关文章

Java HashMap底层实现

HashMap 是 Java 使用频率最高的用于映射&#xff08;键值对&#xff09;处理的数据类型。JDK1.8 对 HashMap 底层的实现进行了优化&#xff0c;例如引入红黑树的数据结构和扩容的优化等。在JDK1.8以前HashMap是由数组链表的数据结构组成的。 Java为数据结构中的映射定义了一个…

java----hashmap底层原理

概述 在Java集合中&#xff0c;Map是一种特殊的集合&#xff0c;原因在于这种集合容器并不是保存单个元素&#xff0c;而是保存一个一个的Key-Vaue键值对.HashMap是基于哈希表的Map接口的实现,在项目开发中使用广泛,下面就对HashMap的源码进行解析. Hashmap的特点 1.HashMap…

HashMap底层数据结构详解

一、HashMap底层数据结构 JDK1.7及之前&#xff1a;数组链表JDK1.8&#xff1a;数组链表红黑树 关于HashMap基本的大家都知道&#xff0c;但是为什么数组的长度必须是2的指数次幂&#xff0c;为什么HashMap的加载因子要设置为0.75&#xff0c;为什么链表长度大于等于8时转成了…

复习一波HashMap底层实现原理解析

HashMap是JAVA中最常见的集合类框架&#xff0c;也是java语言中非常典型的数据结构&#xff0c;同时也是我们需要掌握的数据结构&#xff0c;更重要的也是面试题必问之一。 我们常见的有集合数据有三种结构&#xff1a;1、数组结构 2、链表结构 3、哈希表结构 下面我们来看看各…

HashMap的底层实现

1. HashMap概述&#xff1a; HashMap是基于哈希表的Map接口的非同步实现&#xff08;Hashtable跟HashMap很像&#xff0c;唯一的区别是Hashtalbe中的方法是线程安全的&#xff0c;也就是同步的&#xff09;。此实现提供所有可选的映射操作&#xff0c;并允许使用null值和null键…

HashMap底层特性全解析

文章目录 一、前言二、HashMap2.1 HashMap数据结构2.2 HashMap线程不安全2.3 哈希冲突 三、JDK1.7中HashMap的实现3.1 基本元素Entry3.2 插入逻辑3.2.1 插入逻辑3.2.2 新建节点添加到链表 3.3 数组扩容逻辑3.4 null处理3.5 辨析扩容、树化和哈希冲突 四、JDK1.8中HashMap的实现…

HashMap底层

1、HashMap底层数据结构 JDK1.7的底层是 数组链表&#xff1b; JDK1.8之后 数组 链表 红黑树&#xff1b; 数组特点&#xff1a;具有随机访问的特点&#xff0c;能达到O(1)的时间复杂度&#xff0c;数组查询快&#xff0c;增删比较麻烦&#xff1b; 链表特点&#xff1a;…

HashMap底层实现和原理(源码解析)

Note&#xff1a;文章的内容基于JDK1.7进行分析&#xff0c;1.8做的改动文章末尾进行讲解。 大家可以看一下:https://www.imooc.com/article/267756 一、先来熟悉一下我们常用的HashMap 1、概述 HashMap基于Map接口实现&#xff0c;元素以键值对的方式存储&#xff0c;并且…

HashMap 底层原理

前言 HashMap 源码和底层原理在现在面试中是必问的。因此&#xff0c;我们非常有必要搞清楚它的底层实现和思想&#xff0c;才能在面试中对答如流&#xff0c;跟面试官大战三百回合。文章较长&#xff0c;介绍了很多原理性的问题&#xff0c;希望对你有所帮助~ 正文 **说明&a…

HashMap底层原理剖析(面试收藏!!!)

HashMap HashMap底层原理剖析(超详细&#xff01;&#xff01;&#xff01;)一、散列表结构二、什么是哈希&#xff1f;三、HashMap原理讲解3.1继承体系图3.2Node数据结构分析3.3底层存储结构3.4put数据原理分析3.5什么是哈希碰撞&#xff1f;3.6JDK8为什么引入红黑树&#xff…

HashMap底层原理

文章目录 1.HashMap的概念2.底层数据结构2.JDK1.8之前存在的问题&#xff1f;3.问题&#xff1a;加载因子为什么默认值为0.75f &#xff1f;4.问题&#xff1a;如果得到key的hash值&#xff08;哈希码&#xff09;5.问题&#xff1a;如何得到插入元素在数组中的下标6.问题&…

HashMap 的底层结构和原理

1. 讲讲 HashMap 的底层结构和原理 HashMap 就是以 Key-Value 的方式进行数据存储的一种数据结构嘛&#xff0c;在我们平常开发中非常常用&#xff0c;它在 JDK 1.7 和 JDK 1.8 中底层数据结构是有些不一样的。总体来说&#xff0c;JDK 1.7 中 HashMap 的底层数据结构是数组 …

HashMap底层原理(详细介绍)

数组&#xff1a;其实所谓的数组指的就是一组相关类型的变量集合&#xff0c;并且这些变量彼此之间没有任何的关联。存储区间连续&#xff0c;占用内存严重&#xff0c;数组有下标&#xff0c;查询数据快&#xff0c;但是增删比较慢&#xff1b; 链表&#xff1a;一种常见的基…

HashMap底层详解

1、HashMap底层存储原理详解 HashMap存储原理 ☆获取到传过来的key&#xff0c;调用hash算法获取到hash值 ☆获取到hash值之后调用indexFor方法&#xff0c;通过获取到的hash值以及数组的长度算出数组的下标 (把哈希值和数组容量转换为二进&#xff0c;再在数组容量范围内与哈…

Java基础——工厂模式、单例模式、懒汉模式、饿汉模式

案例&#xff1a; 这里有Factory类、Goods接口、Foods类、Drink类以及Others类。其中&#xff0c;Foods类、Drink类和Others类继承Goods接口&#xff0c;实现各自对应的方法。然后&#xff0c;在测试类中&#xff0c;创建Goods接口指向三个子类中的某一个&#xff0c;通过Facto…

单例模式——饿汉模式和懒汉模式

目录 &#x1f95d;线程安全的单例模式&#x1f95d;饿汉模式&#x1f95d;懒汉模式&#x1f95d; 懒汉模式总结 &#x1f95d;线程安全的单例模式 线程安全的单例模式是面试中常见的问题,所以熟练掌握这种单例模式尤为重要 什么叫单例模式? 单例模式就是一种设计模式,写代码时…

C# 设计模式之单例模式(懒汉模式、饿汉模式、静态内部类模式)

C# 设计模式之单例模式&#xff08;懒汉模式、饿汉模式、静态内部类模式&#xff09; 应用场景&#xff1a;在整个软件运行生命周期内&#xff0c;一个类只允许一次实例化&#xff0c;例如数据库连接池的连接对象创建&#xff1b;通过使用单例模式来避免反复创建连接对象&#…

muduo源码剖析——Singleton单例模式之懒汉模式与DCL双重检查

0 懒汉与饿汉 对于Singleton单例模式我们并不陌生&#xff0c;但我们常用的多是饿汉模式&#xff1a; Singleton实例的声明和实例化在instance()函数中同时完成。而懒汉模式要求&#xff0c;Singleton实例的声明和实例化分开&#xff1a; 先声明Singleton实例对象&#xff0…

C++单例模式 : 懒汉模式 与 饿汉模式

单例模式&#xff1a; 只能有一个实例&#xff0c;有懒汉和饿汉区分&#xff0c;实现核心思想&#xff1a; 1.构造函数私有化 2.使用静态函数作为接口来获取类对象 1、懒汉模式&#xff1a; 由调用者实例&#xff0c;多线程情况下会存在线程安全问题&#xff0c;需要加互斥锁进…

单例模式的创建(饿汉模式懒汉模式)

&#x1f388;专栏链接:多线程相关知识详解 目录 一.什么是单例模式 二.用static来创建单例模式 三.饿汉模式与懒汉模式 四.饿汉模式与懒汉模式的线程安全问题 五.New引发的指令重排序问题 六.小结 一.什么是单例模式 单例模式就是指某个类有且只有一个实例(instance…