前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >HashMap底层结构

HashMap底层结构

作者头像
玖柒的小窝
修改于 2021-11-08 01:37:45
修改于 2021-11-08 01:37:45
6260
举报
文章被收录于专栏:各类技术文章~各类技术文章~

HashMap原理


HashMap的底层数据结构原理

HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干

Put方法的原理

调用 hashMap.put("apple", 0) ,插入一个Key为“apple"的元素。这时候我们需要利用一个哈希函数来确定Entry的插入位置(index):index = Hash(“apple”)假定最后计算出的index是2,那么结果如下

但是,因为HashMap的长度是有限的,当插入的Entry越来越多时,再完美的Hash函数也难免会出现index冲突的情况。比如下面这样

这种情况,可以通过使用链表来解决

HashMap数组的每一个元素不止是一个Entry对象,也是一个链表的头节点。每一个Entry对象通过Next指针指向它的下一个Entry节点。当新来的Entry映射到冲突的数组位置时,只需要插入到对应的链表即可:

需要注意的是,新来的Entry节点插入链表时,使用的是“头插法”

Get方法的原理

使用Get方法根据Key来查找Value的时候,首先会把输入的Key做一次Hash映射,得到对应的index

index = Hash(“apple”)

由于在Hash冲突,同一个位置有可能匹配到多个Entry,这时候就需要顺着对应链表的头节点,一个一个向下来查找。假设我们要查找的Key是“apple”

  1. 我们查看的是头节点Entry6,Entry6的Key是banana,显然不是我们要找的结果
  2. 我们查看的是Next节点Entry1,Entry1的Key是apple,正是我们要找的结果

之所以把Entry6放在头节点,是因为HashMap的发明者认为,后插入的Entry被查找的可能性更大。这就是HashMap的底层原理

HashMap长度

HashMap的默认初始长度是16,并且每次自动扩展或是手动初始化时,长度必须是2的幂

为什么默认长度是16

之所以选择16,是为了服务于从Key映射到index的Hash算法

为了实现高效的Hash算法,HashMap的发明者使用位运算

哈希冲突
哈希冲突解决方法
开放地址方法(再散列法)

可以通俗理解为所有的地址都对所有的数值开放,而不是链式地址法的封闭方式,一个数值固定在一个索引地址位置。

p1=hash(key)如果冲突就在p1地址的基础上+1或者散列处理,p2=hash(p1)

线性探测

按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上往后加一个单位,直至不发生哈希冲突。

再平方探测

   按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上先加1的平方个单位,若仍然存在则减1的平方个单位。随之是2的平方,3的平方等等。直至不发生哈希冲突。

和线性探测相比就是改变探测了步长。因为如果都是+1来探测在数据量比较大的情况下,效率会很差。

伪随机探测

   按顺序决定值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来值的基础上加上随机数,直至不发生哈希冲突。

链式地址法(HashMap的哈希冲突解决方法)

  对于相同的值,使用链表进行连接。使用数组存储每一个链表。

优点:

  • 拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
  • 由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
  • 开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
  • 在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。

缺点:

  指针占用较大空间时,会造成空间浪费,若空间用于增大散列表规模进而提高开放地址法的效率。

建立公共溢出区

  建立公共溢出区存储所有哈希冲突的数据。

再哈希法

  对于冲突的哈希值再次进行哈希处理,直至没有哈希冲突。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
哈希冲突的产生原因及解决方法
‍一、哈希冲突的产生原因 哈希是通过对数据进行再压缩,提高效率的一种解决方法。但由于通过哈希函数产生的哈希值是有限的,而数据可能比较多,导致经过哈希函数处理后仍然有不同的数据对应相同的值。这时候就产生了哈希冲突。
码农编程进阶笔记
2022/08/18
1.2K0
面试难题:为什么HashMap的加载因子默认值是0.75呢?
来源:blog.csdn.net/NYfor2017/article/details/105454097
Java小咖秀
2020/06/24
1.1K0
面试难题:为什么HashMap的加载因子默认值是0.75呢?
进阶 | 我实现了javascript 哈希表,并进行性能比较
前端爱好者的聚集地 javascript的对象就是一个哈希表,为了学习真正的数据结构,我们还是有必要自己重新实现一下。 基本概念 哈希表(hash table )是一种根据关键字直接访问内存存储位置的数据结构,通过哈希表,数据元素的存放位置和数据元素的关键字之间建立起某种对应关系,建立这种对应关系的函数称为哈希函数。 哈希表的构造方法 假设要存储的数据元素个数是n,设置一个长度为m(m > n)的连续存储单元,分别以每个数据元素的关键字Ki(0<=i<=n-1)为自变量,通过哈希函数hash(Ki),把
用户1097444
2022/06/29
7030
进阶 | 我实现了javascript 哈希表,并进行性能比较
Java集合详解(List、Map、Set)
缺点: 指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。
是阿超
2021/10/15
5790
HashMap底层数据结构原理解析[通俗易懂]
老师:JDK中我们最常用的一个数据类是HashMap。那么,谁可以回答一下HashMap的底层数据结构原理是什么呢?
全栈程序员站长
2022/08/31
3890
数据结构——HashMap
众所周知,HashMap 是一个用于存储Key-Value键值对的集合,每一个键值对也叫做 Entry。
全栈程序员站长
2022/08/26
2630
数据结构——HashMap
漫画:什么是HashMap?
众所周知,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。
小灰
2022/07/05
1840
漫画:什么是HashMap?
HashMap(JDK1.8)源码+底层数据结构分析
HashMap 主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一。
黑洞代码
2021/02/09
2580
了解HashMap数据结构,超详细!
HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对。HashMap的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
程序员的时光001
2020/11/02
6190
了解HashMap数据结构,超详细!
HashMap夺命14问,你能坚持到第几问?
在JDK1.7中,由”数组+链表“组成,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
Java技术江湖
2022/04/07
1.5K0
HashMap夺命14问,你能坚持到第几问?
哈希相关知识再学习
在平时工作和源码学习的过程中经常遇到哈希相关的问题,每次都会上网找资料回忆哈希相关的知识点。趁这机会记录下来,防止以后又忘记了!!
静默加载
2020/05/29
7820
hashmap 实现原理_面试hashmap底层实现原理
数组存储区间是连续的,占用内存严重,故空间复杂的很大。但数组的二分查找时间复杂度小,为O(1);数组的特点是:寻址容易,插入和删除困难;
全栈程序员站长
2022/08/02
8641
hashmap 实现原理_面试hashmap底层实现原理
2024年java面试准备--集合篇
Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。
终有救赎
2023/10/16
4600
2024年java面试准备--集合篇
手写HashMap,快手面试官直呼内行!
这……我当时就麻了,我们都知道HashMap的数据结构是数组+链表+红黑树,这是要手撕红黑树的节奏吗?
三分恶
2021/11/29
4610
手写HashMap,快手面试官直呼内行!
由散列表到BitMap的概念与应用(一)
散列表是种数据结构,它可以提供快速的插入操作和查找操作。第一次接触散列表时,它的优点多得让人难以置信。不论散列表中有多少数据,插入和删除只需要接近常量的时间即O(1)的时间级。实际上,这只需要几条机器指令。
aoho求索
2018/12/05
2.2K0
HashMap 精选面试题(背诵版)
对于 Java 求职者来说,HashMap 可谓是重中之重,是面试的必考点。然而 HashMap 的知识点非常多,复习起来花费精力很大。
沉默王二
2021/12/23
7660
HashMap 精选面试题(背诵版)
ArrayMap和HashMap区别
Hash,也可以称为“散列”,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出(也就是多对一的关系)。
Dawnzhang
2018/10/18
2K0
ArrayMap和HashMap区别
散列函数(哈希)(转)
Hash一般翻译作散列也有直接音译作“哈希”。就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。
Oceanlong
2018/12/28
9660
解决哈希冲突的常用方法有哪些?
基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈 希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不 冲突的哈希地址pi ,将相应元素存入其中。
葆宁
2019/04/18
1.3K0
解决哈希冲突的常用方法有哪些?
深入浅出学Java-HashMap
HashMap在JDK1.8之前的实现方式 数组+链表,但是在JDK1.8后对HashMap进行了底层优化,改为了由 数组+链表+红黑树实现,主要的目的是提高查找效率。
Java架构师必看
2021/10/29
3710
深入浅出学Java-HashMap
相关推荐
哈希冲突的产生原因及解决方法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档