Java集合之HashMap的数据结构分析

总所周知,Java中键值对集合,我们最常用的就是HashMap,那么它的数据结构,以及如何存储键值对,包括为什么使用红黑树,链表等许多数据结构,下面我们一起学习交流

1.HashMap的数据结构:

HashMap的数据结构采用:数组(哈希表)+链表+红黑树
1.数组(哈希表):
    HashMap内部定义了一个数组,数组中的每个位置被称为“桶”(Bucket),这是HashMap的基础结构【哈希表】;
    下标位置:当添加一个新的key-value 键值对时,会根据key的hashcode(),通过哈希函数(也叫哈希干扰函数)计算出一个新的哈希值 hash,并通过这个 hash值,计算key-value键值对在数组中的下标位置(桶,Bucket)
    数组容量:在添加第一个key-value键值对时,数组容量被初始化为16,并且可以根据key-value键值对的数量和负载因子(加载因子),数组会自动按照两倍扩容
2.链表:
    数组的每个位置(Bucket 桶)可以保存一个或多个key-value键值对
    当两个或更多的key-value键值对,被映射到数组的同一个位置(桶,bucket)时,就产生了哈希冲突
    HashMap使用链地址法,解决哈希冲突,这些键值对将以链表的形式存储在产生冲突的位置(桶,Bucket)

3.红黑树:
    为了优化链表的查询性能,当链表长度超过一个阈值(默认是8)并且数组的容量大于等于64时,链表会转换成红黑树
    红黑树是一种自平衡的二叉查找树,它可以基于二分查找的方式,进行元素的查找,提高查找性能,这对于较长的链表来说是一个明显的性能提升
    当红黑树中的节点数量减少到6各或更少时,红黑树转换回链表
   

.HashMap如何计算key-value键值对元素在数组中的存储位置:

为了时key-value元素可以均匀散列的保存在HashMap的数组中,所以使用key的哈希值进行哈希扰动函数计算出一个新的hash值
在JDK1.8版本之前,HashMap会将这个hash值与数组长度进行%模运算出一个下标,从而确定key-value在数组中的存储位置
    例如:数组长度默认为16,12580%16=4,753951%16=15,所以哈希值为12500,753951的键值对,会存储在数组下标为4和3的位置

在JDK1.8版本以后,由于% 模运算性能消耗比较大,所以采用(长度-1)&hash的位运算来计算存储位置
    例如:数组长度默认为16,(16-1)&12580=4,(16-1)&753951 ,所以哈希值为12580,753951的键值对,会继续存储在数组下标为4和3的位置。

HashMap的扩容机制?

HashMap的用来进行扩容的方法是resize();
HashMap在以下三种场景下,会触发扩容机制:
    1.当HashMap通过无参构造方法创建,在第一次调用put()方法添加key-value键值对时,数组初始化为16;
    2.当HashMap中的元素个数超过扩容阈值threshold时,数组的容量按照原容量的2倍进行扩容:
        扩容阈值threshold=数组容量×加载因子LoadFactor
        加载因子LoadFactor的默认值为0.75,数组容量默认为16,扩容阈值threshold默认值为12(16*0.75=12);
        所以,当HashMap中元素个数超过12时,数组的容量按照原容量的2倍进行扩容(16*2=32);
    3.加入元素时,如果链表长度大于阈值(默认为8)并且数组长度小于64,会产生数组扩容

HashMap为什么使用链表?

HashMap使用哈希表作为基础数据结构,当两个不同的key-value键值对,通过hash哈希值计算数组下标,出现像疼痛下标情况时,产生哈希冲突
HashMap使用”链地址法“解决哈希冲突,所以需要使用链表,来保存产生哈希冲突的key-value键值对

HashMap为什么使用红黑树?

HashMap中的链表长度增长到一定长度,会导致搜索性能下降(链表是线性方式搜索)
所以,HashMap会在链表过长,将链表转换为红黑树,通过红黑树提供搜索性能(红黑树是二分查找方式搜索)

HashMap不直接使用红黑树的原因:链表简单易于维护,红黑树维护复杂,所以首选使用链表,只有链表长度过长时,才会转换成红黑树来提高搜索查找的性能。

HashMap,LinkedHashMap,TreeMap的区别?

HashMap:无序,基于数组+链表+红黑树实现;
LinkedHashMap:有序,HashMap的子类
TreeMap:自动排序,按照key或者自定义Comparator比较器,进行排序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50629.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scratch二次开发:如何修改toolbox宽度

大家好,我是小黄。 使用场景:有时候我们开发图形化编程时,我们的积木块很长,导致一部分无法显示,我们想要把目录区域位置放大,比如下面红色方框区域位置,那么改如何实现这个过程呢?…

Qt,获取其他.exe文件的标准输出流的信息(printf/print的输出信息)

比如,通过Python编写爬虫软件功能是运行程序获取豆瓣电影排行榜信息,并通过print打印出来。将其打包成.exe,通过Qt来调用,并获取到.exe程序运行的结果 简单示例代码: // 创建 QProcess 对象QProcess process;// 连接信号槽以获取…

嵌入式学习Day14---C语言进阶

目录 一、构造类型 1.1.结构体 1.存储 2.输入输出(传参) 3.结构体数组 1.2.共同体(联合体) 1.格式 2.存储 3.测试一个平台是打端还是小端 1.3.枚举 1.格式 2.特点 二、位运算(操作二进制) 2.1.&a…

培训第十六天(web服务apache与nginx)

上午 静态资源 根据开发者保存在项目资源目录中的路径访问静态资源html 图片 js css 音乐 视频 f12,开发者工具,网络 1、web基本概念 web服务器(web server):也称HTTP服务器(HTTP server)&am…

翻译: 可视化深度学习神经网络一

这是一个随意书写的28*28像素、分辨率很低的数字 3 但你的大脑一看见就能轻松辨识出来 ,我想要你好好欣赏这点 人脑能够毫无障碍地辨识是非常厉害的 我的意思是,这个、这个、还有这个,都能被识别为 3 即使前后图像的图形组成有很大差异 当你…

懂个锤子Vue 项目工程化扩展:

Vue项目工程化扩展📶: 前言:当然既然学习框架的了,HTMLCSSJS三件套必须的就不说了: JavaScript 快速入门 紧跟前文,目标学习Vue2.0——3.0: 懂个锤子Vue、WebPack5.0、WebPack高级进阶 涉及的…

WEB前端开发中如何实现大文件上传?

大文件上传是个非常普遍的场景,在面试中也会经常被问到,大文件上传的实现思路和流程。在日常开发中,无论是云存储、视频分享平台还是企业级应用,大文件上传都是用户与服务器之间交互的重要环节。随着现代网络应用的日益复杂化&…

康师傅JAVA核心内容

链接:康师傅JAVA核心内容 (qq.com)

黑龙江等保测评如何做到既全面又高效?

在黑龙江省进行等保测评,必须在全面和高效之间寻求一个平衡点,以保证网络的安全性和可靠性。黑龙江等保测评怎样才能在二者之间发现黄金交汇点?下面,我们来揭开谜底。 精准定位,明确测评范围 首先,一个综…

Docker与LXC差异以及相关命令

容器:Docker与LXC差异以及相关命令 ​ LXC与Docker对比,LXC只实现了进程沙盒化,不支持在不同的机器上进行移植;Docker将应用的所有配置和环境进行了抽象,打包到一个容器中,此容器可以在任何安装了docker的…

vscode搭建rust开发环境

由于rustrover不是免费的,此处教学搭建一套基于vscode的rust开发环境,可运行,可调式 1.下载vscode1.91.1 Download Visual Studio Code - Mac, Linux, Windows 2.下载插件 打开网站下载插件 rust-analyzer-0.4.2049、vscode-lldb-1.10.0、…

IDEA项目的依赖(pom.xml文件)导入问题及解决

前言:该文章为转载,没有仔细的看 IDEA新建项目和pom.xml文件被修改时,右下角都会出现 Maven projects need to be imported(项目需要导入依赖) 如下,点击 Import Changes导入后,有时会一直处于…

NAS、SAN 与 DAS 的比较与应用场景

文章目录 1. NAS(网络附加存储)定义特点实现成本:适用场景 2. SAN(存储区域网络)定义特点实现成本:适用场景 3. DAS(直接附加存储)定义特点实现成本:适用场景 区别总结结…

Redis学习[1] ——基本概念和数据类型

Redis学习[1] ——基本概念和数据类型 一、Redis基础概念 1.1 Redis是什么,有什么特点? Redis是一个基于**内存的数据库,因此读写速度非常快**,常用作缓存、消息队列、分布式锁和键值存储数据库。支持多种数据结构:…

Java 内推 | 教育行业缺口来了,研发,运维,产品,教研,职能,营销... 别错过

Java 内推 | 教育行业缺口来了,研发,运维,产品,教研,职能,营销… 别错过 岗位职责: 1、根据公司战略及业务规划,参与部门业务架构分析与设计,包含规划立足当前、面向未来的应用架构…

源码编译安装,及nginx服务控制、监控块

1.源码编译安装: [root17dns ~]# wget https://nginx.org/download/nginx-1.27.0.tar.gz 2.解压: [root17dns ~]# tar -zxvf nginx-1.27.0.tar.gz 3.安装gcc等工具 [root17dns ~]# yum -y install gcc gcc-c [root17dns ~]# yum -y install make lrzsz …

postman给全部接口添加请求头数据(如token)

如果给没有一个接口添加请求头token就太慢了,如下图。可以点击所有接口的所属的目录。点击“Scripts”,点击Pre-request按钮。加入代码: pm.request.addHeader("Authorization:eyJhbGciOiJIUzI1NiIsInR5cCI111pXVCJ9.eyJjbGFpbXMiOnsiaW…

小红书笔记评论采集全攻略:三种高效方法教你批量导出

摘要: 本文将深入探讨如何利用Python高效采集小红书平台上的笔记评论,通过三种实战策略,手把手教你实现批量数据导出。无论是市场分析、竞品监测还是用户反馈收集,这些技巧都将为你解锁新效率。 一、引言:小红书数据…

项目实战_表白墙(简易版)

你能学到什么 一个比较简单的项目:表白墙(简易版),浏览器:谷歌升级版将在下个博客发布 效果如下 正文 说明 我们是从0开始一步一步做这个项目的,里面的各种问题,我也会以第一人称视角来解…