HashMap底层实现原理

HashMap与HashSet的底层实现原理 本篇文章将介绍Java中HashMap的底层实现原理,有关HashMap为数组开辟内存的时期,默认的容量,默认负载因子,树化的条件,HashMap的扩容机制,put方法的过程以及HashMap中的哈希函数。 阅读详情

HashMap是我们常用的数据结构,是一种有由数组和链表组成的数据结构
数组里每个地方都保存了Key-Val这样的实例,JAVA7叫Entry,JAVA8叫Node
但是它的本身就是Null,所以在put进行时,会根据key的hash去计算一个indext值(也就是插入位置)
hash具体是怎样计算的呢
源代码里是这样实现的
hash=(hash>>16)^hash
index=(array.length-1)&hash

我们需要得到合法下标,必须在[0,array.length)中,不可以直接传入hash作为index,
有时候可能会想我们可以直接通过hash%array.length得到合法下标。但是这种操作
相比较mod操作来说太慢了,所以我们使用上述方式。
但是这种方式有一个条件那就是array.length必须是2的n次方,比如说 16 32 64 128
又因为只进行index=(array.length-1)&hash的话,能被利用的只有后面几个二进制位,可能会导致下表不均匀,所以说我们需要hash=(hash>>16)^hash右移16位之后进行异或操作,使得下标尽可能均匀。
这里再来谈一谈数组的扩容,因为随着不断地Put进去Key,我们的初始数组容量是不够的,在HashMap底层扩容机制是这样的,它设置了负载因子,
负载因子=Key的size/数组的length
阙值是0.75,
因为 根据泊松分布,在负载因子默认为0.75的时候,单个hash槽内元素个数为8的概率小于百万分之一,所以将7作为一个分水岭,等于7的时候不转换,大于等于8的时候才进行转换,小于等于6的时候就化为链表。
我们在阙值到来的时候必须降低负载因子所以我们就要扩容
在这里提一下,这里的扩容和顺序表的扩容是不一样的
顺序表的扩容是为了解决放不下的问题
哈希表的扩容是为了解决冲突的问题
直接在原有基础上扩容两倍,总体步骤是这样的
1.扩容:创建一个新的Entry数组,长度是原来数组的两倍
2.ReHash:遍历原Entry数组,把所有的Entry重新Hash到新数组。
这里我们第一感觉就是,为什么还要重新Hash呢???直接复制过来不香吗
对于这个问题我们就得回到之前的公式index=(array.length-1)&hash
长度变化了所以位于出来的自然就不一样了!!

我刚才提到了链表,为什么会有链表,因为我们知道在有限的长度里使用哈希,哈希本质就带有随机性,我们两个Key得到了相同的hash就形成了链表,我们以这种方式解决哈希冲突。这里说一下冲突不剧烈的情况下整体时间复杂度是0(1),因为链表冲突不剧烈很短可以看作O(1),O(1)+O(1)=O(1)
我们再来说一说插入链表时候的操作,总体是这样的JDK8之前都是头插法,就是说新来的值会取代原有的值,原有的值就顺推到链表中去,因为写这个代码的作者认为后来的值被查找的可能性更大一点,提升查找的效率。,JDK8之后就变成了尾插法。
这是为什么呢???
因为HashMap在多线程环境下,运行多个线程插入时,我们在没resize前就插入完成,这就会导致,因为resize的赋值方式,也就是使用了单链表的头插方式,同一位置上的新元素总会被放在链表的头部位置在旧数组中同一条Entry链上的元素,通过重新计算索引位置后,有可能被放到了新数组的不同位置上。这就有可能会出现环形链表
如果这时候去取值就会报错。
运用头插之后就没有这种问题了,这里再说一下JDK8链表超过8就会变成红黑树,这里巧妙地将时间复杂度,0(n)变成了O(logn).关于这个数据给狗我过几天复习数据结构的时候再来阐述。

JDK1.8HashMap底层实现原理 hashmap是我们开发中用的最常见的集合之一,但是我们是否有了解过他的底层呢?这篇文章我将带您了解一下hashmap的底层 位运算 在学习hashmap底层原理的时候,我们必须要掌握位运算,别问为什么,往下面看自然知晓 ... 阅读详情

相关推荐

Cobalt Strike4.0安装包(内附中文版)

1.什么是 Cobalt Strike Cobalt Strike 是一个为对手模拟和红队行动而设计的平台,主要用于执行有目标的攻击和模拟高级威胁 者的后渗透行动。 Cobalt Strike已经不再使用MSF而是作为单独的平台使用,它分为客户端与服务端,服务端是一个,客户端可以有多个,可被团队进行分布式协团操作。集成了端口转发、扫描多模式端口Listener、Windows exe程序生成、W...

梦之序章的博客 2万+

HashMap的底层实现原理

HashMap底层实现原理

qq_45621240的博客 7989

【上海大学计算机组成原理实验报告】七、程序转移机制

学习实现程序转移的硬件机制//掌握堆栈寄存器的使用//手动方式实现子程序调用转移过程//手动方式实现子程序返回转移过程//编程实现`OUT`寄存器交替显示`11`和`55`//若要求`11`和`55`各显示`50`次后停机,应该如何修改程序?//根据实验指导书的相关内容,实验箱系统的程序转移硬件机制在于,当`LDPC`有效时,如果此时`DUBS`上的值就是转移的目标地址,则此目标地址被打入`PC`,从而实现程序的转移;若`LDPC`为`0`是附带条件的,就形成“条件转移”。

HackerKevon的博客 2473

HashMap底层原理

1、哈希映射:通过哈希函数计算键的哈希值,并决定存储位置。2、链表和红黑树:用于解决哈希冲突,链表长度超过阈值时转化为红黑树。3、扩容和再散列:当元素数量超过一定阈值时,数组扩容,并重新分配元素的位置。

qq_45737165的博客 7122

Chapter2、HDR流水线

HDR内容的获取(不同曝光时间的图片合成) 相机响应函数 HDR视频

qq_55621259的博客 2597

【STM32学习】(29)STM32实现595驱动三个数码管(标准库和HAL库实现)

我选用的单片机型号为:STM32F103系列 74LS595是一个串转并行输出的芯片,它能为单片机节省很多的IO口,应用场景广泛。 现要求三个数码管动态显示,常规设计都是并行实现,需要8个IO数据口,然后还需要3个IO片选数码管接口,这样大大占用了IO口,导致连接的外设变少。因此我们引入74LS595芯片。电路设计如下: 只需要三个共阴极数码管与三个595芯片级联即可完成,通过RCLK,SCK,SER三个IO即可完成对数码管的动态控制并显示。电路焊接的实物图如下: 要求完成功能:实现数.

XiaoCaiDaYong的博客 8264

HashMap底层原理(超详细)

因为存储的数据,不是按顺序存的,是按hash值当下标存储的,每个对象的hash值不同,下标也就不固定,所以是无序的。

weixin_72504091的博客 7659

用树莓派Pico低成本更新USB-C PD控制器固件实战指南

固件更新是嵌入式系统开发与维护中的核心环节,它直接决定了硬件设备的功能、性能与兼容性。其原理通常是通过特定的通信接口(如SWD、JTAG、UART或USB)与设备内部的Bootloader建立连接,将新的程序代码安全写入非易失性存储器。在USB Power Delivery(PD)和Type-C生态中,固件更新技术尤为重要,它能修复协议握手Bug、适配新设备并提升供电策略的灵活性。本文聚焦于一个典型的工程实践场景:如何利用广泛普及且成本极低的树莓派Pico开发板,作为USB-C协议到I²C协议的转换桥,实现

weixin_27869497的博客 458

HashMap底层实现原理?着这一篇就够了

HashMap底层实现原理?着这一篇就够了

weixin_42113716的博客 7623

AI工作流革命:从n8n到Sora2,揭秘自动化视频创作的底层逻辑

本文深入探讨了AI工作流在自动化视频创作中的应用,重点介绍了n8n、Coze和Sora2的组合如何实现从链接输入到视频输出的全流程自动化。通过三层架构解析、关键技术模块优化及成本控制策略,这套方案显著提升了视频生产效率,适用于电商、热点追踪等多种场景。

gg901的博客 1083

ROCm rocr-libhsakmt分析系列1-2:多GPU跨卡VRAM访问机制分析

本文基于ROCr-Runtime的libhsakmt库源码,深入分析了多GPU系统中跨设备内存访问的实现机制。主要内容包括: 实现流程概述:通过P2P拓扑发现、统一虚拟地址空间、页表映射和硬件转发四个步骤,实现零拷贝的跨GPU内存访问。

图形/计算GPU的驱动与虚拟化技术分享园地 2505

HashMap底层实现原理解析

一:HashMap底层实现原理解析 我们常见的有数据结构有三种结构:1、数组结构 2、链表结构 3、哈希表结构 下面我们来看看各自的数据结构的特点: 1、数组结构: 存储区间连续、内存占用严重、空间复杂度大 优点:随机读取和修改效率高,原因是数组是连续的(随机访问性强,查找速度快) 缺点:插入和删除数据效率低,因插入数据,这个位置后面的数据在内存中都要往后移动,且大小固定不易动态扩展。 2、链表结构:存储区间离散、占用内存宽松、空间复杂度小 优点:插入删除速度快,内存利用率高,没有固定大小,扩展灵活

qq_43370771的博客 12万+

使用C++实现DNS欺骗攻击

其中,domain_name表示需要欺骗的域名,dns_server_ip表示实际DNS服务器的IP地址,fake_ip表示需要重定向到的IP地址。在DNS查询过程中,当客户端向DNS服务器请求解析某个域名时,DNS服务器会返回该域名对应的IP地址。DNS劫持是一种常见的网络攻击方式,通过篡改DNS响应数据,使得用户访问的网站被重定向到攻击者指定的恶意站点。我们使用C++编写一个简单的DNS欺骗程序,使得当客户端请求解析特定的域名时,我们可以将其重定向到指定的IP地址。使用C++实现DNS欺骗攻击。

TechGlide的博客 411

HashMap底层实现原理详解

本文深入讲解了Java中HashMap的实现原理与特性。首先介绍了HashMap的基本概念和常用方法,包括put、get、remove等操作。然后分析了JDK7和JDK8中HashMap的区别,指出JDK8引入了红黑树优化性能。重点解析了HashMap的扩容机制和容量设计,包括默认负载因子0.75的合理性、扩容规则以及初始容量16的原因。最后比较了不同JDK版本下HashMap的结构变化,JDK7使用数组+链表,而JDK8优化为数组+链表+红黑树的结构,并改变了节点插入顺序。文章通过详细的源码分析和问题解答

Hai的博客 2万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

HashMap 底层实现原理

要了解HashMap的底层实现原理,我们首先要对HashMap的部分底层源码进行分析 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable 我们可以看出HashMap继承了AbstractMap,实现了Map,Cloneable,Serializable接口。 static final int DEFAULT_I

wenkezhuangyuan的博客 2967

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【java】HashMap底层实现原理

【java】HashMap底层实现原理及面试题

酷酷的馫博客 2万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: 网络复习之网络传输基本流程
下一篇: ConcurrentHashMap实现原理
KILLBILLKILLING
博客等级 码龄8年 3粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值