HashMap超详解

HashMap之resize详解 文章目录1. 导读2. HashMap为什么要扩容3. HashMap何时扩容3. 为什么是0.754. HashMap如何扩容5. JDK8对JDK7的优化 1. 导读 上期分享了HashMap的key定位以及数据节点的设计, 本期就下面三个问题来分享下个人对于HashMap扩容的理解: .1 HashMap为什么要扩容? 何时扩容? .2 负载因子为什么是0.75? .3 HashMap如何扩... 阅读详情

内部数据结构

JDK1.8为例,内部使用数组+链表/红黑树的实现方式
学过数据结构的都知道拉链法构造哈希表,这就是通过拉链法构造的过程。
但是也有区别,当因哈希碰撞形成的链表长度超过8且数组大小超过64(包含64)时,会变成红黑树,提高查找的效率。
当红黑树节点小于6时,又会转化回链表。

数据插入原理

1.判断数组是否为空,若为空则初始化数组,否则,通过计算(n-1)&hash值得到存储的位置。
2.通过查看计算出的位置是否已经存在数据判定是否发生了hash冲突,如果没有,则存放节点,若有,则比较原本的key,如果相等,则覆盖并返回旧的值,如果不相等,则判定该节点是否是红黑树节点,如果是,则插入树,如果不是则插入链表,同时判定插入链表后是否长度超过了8,如果超过了则转换为红黑树。
3.当上述操作完成后再判断数组中节点数是否超过了阈值,如果超过则进行扩容。扩容操作为左移一位,即变两倍。

初始化设置

当调用无参构造方法时,HashMap会使用默认设置,默认大小为16,负载因子是0.75。
当调用有参构造方法时,如new HashMap(a),则大小为>=a的2的整数次幂。
具体计算方式为
int n=a-1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n<0)?1:(n>=MAXIMUM_CAPACITY)?MAXIMUM_CAPACITY:n+1;
这样可能有点抽象,通俗的说就是
将这个数二进制右移,并与自身异或,将第一个1不断右移,即所有位全部变成1后再加1,即得到了第一位是1,后面全是0的二进制数,这样的数就是2的整数次幂。

HashMap中的哈希函数

哈希函数先拿到key的hashcode(Java所有类都继承了Object类,hashcode默认情况下是它的内存地址,为32位的int值),然后将hashcode的前16位与后16位进行异或。又称扰动函数。
如此设计的原因:可以减少哈希碰撞发生次数,位运算效率比较高。
详细解释:上面提到,散列值是一个32位的int类型数,映射空间过于庞大,大约有40亿,内存不可能存放,并且如果采用常见的取模哈希函数,效率很低。因此使用n-1&hashcode的方法来进行计算,可以把第一个非0高位1后面的所有数截取出来,从而提高了效率。
但是若只是采用这种方式得到的存放位置,碰撞现象是很容易出现的,就算不出现,也会造成入碎片状的内存,因此需要扰动函数。
通过将前后16位进行异或,可以让前后信息都存在,从而更容易将数与数之间区分开。

HashMap的优化

1.扰动函数只进行1次。(实际证明,1次就够了)
2.加入了红黑树,链表长度超过8且数组长度超过64时会转化为红黑树,红黑树节点少于6时则会转换为链表。(降低复杂度)
3.链表的插入方式从头插法改为了尾插法。(头插法容易在多线程环境形成环,扩容情况下链表反转)
4.改为先插入再扩容。(提高效率)
5.不再需要重hash就可以确认位置。(提高效率)

是否支持同步

不支持同步。若要支持同步,可以使用synchronizedMap方法,Hashtable和ConcurrentHashMap来替代HashMap。
Hashtable简单使用的synchronized锁,效率很低,同时也不支持空值,而HashMap支持Null。
而synchronizedMap方法使用对象锁。
ConcurrentHashMap的话1.7以前使用的是分段锁,提高并发量,1.8后使用加入了synchronized和CAS(compare and swap)。
所谓分段锁就是将数据分段,彼此互不影响,具体实现即将成员变量用volatile修饰(补充:volatile两个作用,一是保证变量透明,二是防止指令重排,所谓变量透明即每次访问这个变量时要从主存读取,不能从内存读取,防止多线程操作下数据不一致的问题。)然后使用CAS和synchronized实现赋值(CAS简单说就是将预期值和实际值比较若相同则直接进行交换,无需再次从主存访问)。

哈希碰撞发生时的链树转换阈值

链表变成红黑树需要长度超过8,红黑树变回链表则需要节点少于6.
hash碰撞8次的概率很低,所以设置8为界限,但是如果少于8就将红黑树变成链表,会出现一个问题,反复发生转换造成效率低下,因此设置为6.

有序性

HashMap是无序的,若需要有序的HashMap,可以使用LinkedHashMap和TreeMap

LinkedHashMap

底层实现是一个双节点的单链表,节点继承HashMap的节点,并拥有前后节点的标记,因此可以进行排序。

TreeMap

底层实现是红黑树,可以通过实现Comparable接口也可也实现Comparator比较器来定义一个排序方法。进行排序。

基于MAP的图像超分辨率重建算法 介绍了一种基于MAP的图像超分辨率重建算法 立即下载

相关推荐

【Diffusion分割】医学图像分割中去噪扩散技术

扩散模型(DPM)在图像生成方面表现出了卓越的性能,其性能往往优于其他生成模型。自其问世以来,强大的噪声-图像去噪管道已被扩展到各种判别任务中,包括图像分割。在医学成像中,图像往往是大型三维扫描图像,由于内存消耗大、迭代采样过程耗时,使用 DPM 对一幅图像进行分割的效率极低。在这项工作中,我们提出了一种(LDSeg),可在潜空间中执行扩散,用于医学影像分割。我们。潜空间条件扩散不仅能确保对多标签对象进行精确的 n-D 图像分割,还能缓解基于 DPM 的传统分割法的主要潜在问题:(。

qq_43583311的博客 1171

HashMap详解

学hashmap,这一篇就足够了

LZH~天的博客 2020

10-142 6-4 查询厂商“D“生产的PC和便携式电脑的平均价格

分数 10全屏浏览题目切换布局作者 lhm单位 河北农业大学本题目要求编写SQL语句,查询厂商D生产的PC和便携式电脑的平均价格。

dqd66的博客 2748

HashMap在jdk1.7和jdk1.8中的区别

一、初窥HashMap HashMap是应用更广泛的哈希表实现,而且大部分情况下,都能在常数时间性能的情况下进行put和get操作。 jdk1.7中底层是由数组(也有叫做“位桶”的)+链表实现;jdk1.8中底层是由数组+链表/红黑树实现 可以存储null键和null值,线程不安全。在HashMap中,null可以作为键,这样的键只有一个,但可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该key,也可以表示该key所对应的value为null。因

qq_34325438的博客 2601

硬件测试入门--环路响应(Bode)测试

环路分析的一个重要作用就是分析开关电源的稳定性。扫频测试原理主要是给开关电源电路注入一个频率变化的正弦信号,测量开关电源在频域上的特性,通过分析穿越频率、增益裕度和相位裕度来判断环路是否稳定,可以为电子工程师设计稳定的控制电路提供直观的数据。开关电源的稳定性关系到整个应用系统的可靠性,利用伯德图可以看出在不同频率下系统增益的大小和相位。通过伯德图来对开关电源的环路稳定性进行判断和分析已经成为评估开关电源可靠性必不可少的方法。

songninging的博客 1万+

[Dify实战] 多轮对话状态管理:上下文保持与槽位填充

本文探讨了基于LLM的对话应用中多轮对话状态管理的核心挑战与解决方案。文章指出,单纯的"能聊"远远不够,关键在于建立有效的状态管理机制,包括上下文保持和槽位填充两大核心能力。通过Dify实战视角,详细阐述了如何设计工程化落地方案:采用混合策略的上下文管理(窗口+摘要+关键槽位)、JSON Schema强约束的槽位抽取、统一状态对象存储、冲突处理机制和优化追问策略。文章特别强调,合理的状态管理能将"聊天"转化为"可执行的业务流程",避免模型成为&qu

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 235

HashMap 源码解析超详解

对java 1.8以后的hashMap的源码进行了介绍

qq_45515347的博客 515

Milvus 向量数据库部署方案全景指南:从单机开发到生产级高可用集群

本文系统介绍了Milvus向量数据库的四大部署方案:嵌入式开发利器Milvus Lite、单机简易部署Standalone模式、生产级高可用Cluster模式以及全托管SaaS服务Zilliz Cloud。针对不同应用场景(开发测试、小型应用、大规模生产环境),详细分析了各模式的适用条件、资源配置要求和部署步骤,并提供了关键配置示例。文章强调正确选择部署方案对系统性能至关重要,帮助开发者根据向量规模、QPS和高可用需求,选择最优部署方式,实现资源优化与稳定运行。

reset2021的博客 385

HashMap的存储底层源码超详解

HashMap源码低层储存,hashMap.put()方法,putVal()方法,链表转化红黑树,hashMap存储结构,重复字符个数

罗铠威的博客 208

基于Simulink的自适应反步法(Adaptive Backstepping)控制​

本文针对非线性系统控制中未知参数和强非线性耦合的挑战,提出基于Simulink的自适应反步法解决方案。通过融合参数在线估计与反步递归设计,该方法显著提升了永磁同步电机(PMSM)速度控制的鲁棒性,使跟踪误差从20%降至3%,参数估计收敛时间小于0.5秒。文章详细阐述了从算法推导到Simulink实现的完整流程,包括系统架构设计、核心算法推导(以PMSM为例)、模块化建模方法、参数优化策略以及工程部署建议。提供的自适应控制器MATLAB代码和关键参数表可直接应用于实际工程,为电机驱动、机械臂等非线性系统控制提

xiaoheshang_123的博客 101

MAC-电脑中的user文件夹在哪?

MAC-电脑中的user文件夹在哪?

兴趣是最好的老师 1万+

HashMap原码分析(超详解)

1.首先我们在new一个HashMap的时候,我们并不会创建一个数组,而只是赋予了一个加载因子(默认值0.75)。如果你自己传入了一个大小,那么就会它就会调用一个tableSizeFor这个函数来规定,使你的数值一定是2的N次幂。如果我们传入的是15,那么经过tableSizeFor运算之后就会变成16(当然不能超过最大值1<<30) 2.当我们使用put来存值的时候,那么我们的HashMap结构才开始展示出来。 首先我们会调用resize这个方法来对hashMap进行赋值...

qq_51931928的博客 202

【数据湖仓】:Iceberg、Hudi 和 Paimon 对比

适用于需要多计算引擎支持和复杂查询的离线批处理场景。其中立性和灵活性使其成为构建新型数据平台的理想选择。:在需要高频数据更新和高效小文件管理的场景中表现出色,适合实时数据处理和增量数据更新的业务需求。:专为实时流式数据处理设计,适用于对数据实时性要求高的业务场景,如实时数据分析和实时指标监控。通过以上分析,可以看出 Apache Iceberg、Apache Hudi 和 Apache Paimon 各有其独特的优势和适用场景。企业应根据自身业务需求和技术栈选择合适的数据湖仓方案,以充分发挥其价值。

欢迎来到我的博客,一起探索代码里的世界! 1607

HashMap源码详解(超简单易懂版)

1:什么是HashMap? 面试时候如果这样问,就答下面几点: 1:HashMap是Java中一种常用的数据结构,继承了AbstractMap类,并且基于哈希表实现了Map接口。 2:存储方式是key-value键值对,使用非常方便,同时允许一个null作为键,允许多个null作为value。 3:HashMap是线程不安全的。 4:HashMap底层是数组+链表,当链表深度超过8时会优化转为二叉...

whiteBearClimb的博客 520

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

HashMap超全源码详解(JDK1.8)

HashMap基于哈希表的Map接口实现,是以key-value存储形式存在。JDK1.8版本中其数据结构是:数组+链表+红黑树的形式。下面详解源码及解决的问题。 接口方法:成员变量:1.put方法源码及总结总结:2.get方法源码及总结总结:3.resize(扩容)方法源码及总结总结:由JDK1.7的,数组 + 链表JDK1.8变为:数组 + 链表 + 红黑树具体触发条件为:某个链表连接的个数大于8,并且总的容量大于64的时候,那么会把原来的链表转换成红黑树。这么做的好处是什么:红黑树除了添加元素外,

xiaoyya的博客 987

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

hashmap是否有序_HashMap集合超详解 - 深入理解Java面试题

一、HashMap 集合简介 HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的 key、value 都可以为 null,此外,HashMap 中的映射不是有序的。 jdk1.8 之前 HashMap 由 数组 + 链表 组成,数组是 HashMap 的主体,链表则是主要为了...

weixin_39569894的博客 413

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【HashMap】HashMap源码put方法分析(jdk1.8超详解)

1、代码创建一个变量oldTab,并将其赋值为table数组。table数组是HashMap中存储元素的数组。2、代码使用三元运算符判断oldTab是否为null,如果是null,则表示原来的HashMap没有任何元素,将旧的容量oldCap设置为0;否则,将旧的容量oldCap设置为oldTab数组的长度。3、代码将阈值threshold赋值给变量oldThr。threshold是HashMap中的一个属性,表示数组需要进行扩容的阈值。

miles067的博客 294

jdk1.7HashMap扩容源码超详解析!

jdk1.7 HashMap扩容源码详解

weixin_44154094的博客 570

Java 中的集合框架之 Map接口、HashMap 类、HashTable 类、TreeMap 类(1万字超全详解)

接口描述Collection 接口Collection 是最基本的集合接口,一个 Collection 代表一组 Object(即 Collection 的元素), Java不提供直接继承自 Collection的类,只提供继承自 Collection 接口的子接口(如 List和 set)。Collection 接口存储一组不唯一,无序的对象(不能通过索引来访问 Collection 集合中的对象)。List 接口。

林二月的博客 1799

C++ map和HashMap原理详解_c++ map根据key获取value的原理(1)

上面可以看到Map接口的几个实现方式。简要说明:TreeMap是基于树(红黑树)的实现方式,即添加到一个有序列表,在O(log n)的复杂度内通过key值找到value,优点是空间要求低,但在时间上不如HashMap。C++中Map的实现就是基于这种方式HashMap是基于HashCode的实现方式,在查找上要比TreeMap速度快,添加时也没有任何顺序,但空间复杂度高。C++ unordered_Map就是基于该种方式。

2401_87256961的博客 841

HashMap扩容过程是什么?怎么解决哈希冲突?

hello啊,各位观众姥爷们!!!本baby今天又来报道了!哈哈哈哈哈嗝🐶。

牛马baby的博客 999

HashMap扩容机制

本文对比了JDK7和JDK8中HashMap的扩容机制。JDK8进行了两项重要优化:将头插法改为尾插法,解决了多线程扩容时的死循环问题;通过hash&oldCap判断高低位,避免重新计算所有hash值。扩容触发条件是元素数量超过capacity×0.75(默认16×0.75=12)。JDK8采用高低位迁移策略,根据hash值的特定位判断元素在新数组中的位置,提高迁移效率。文章建议初始化时预估容量以避免频繁扩容,并提供了面试回答模板。

慢慢 243

HashMap 详解

一、数据结构 1、HashMap是Java中最常用的集合类框架,也是Java语言中非常典型的数据结构, 2、数组特点 存储区间是连续,且占用内存严重,空间复杂也很大,时间复杂为O(1)。优点:是随机读取效率很高,原因数组是连续(随机访问性强,查找速度快)。缺点:插入和删除数据效率低,因插入数据,这个位置后面的数据在内存中要往后移的,且大小固定不易动态扩展。 3、链表特点 区间离散,占用内存宽松,空间复杂度小,时间复杂度O(N)。优点:插入删除速度快,内存利用率高,没有大小固定,扩...

shi_xiansheng的博客 10万+
上一篇: Session、Cookie、JWT详解
下一篇: MySQL中的sql语句执行过程
Tate_Brown
博客等级 码龄9年 39粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值