Map (三) HashMap 如何利用 hash 计算存储位置

HashMap 的底层实现(判断元素存放的位置,解决哈希冲突,优化扩容) 在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;链表的特点是:寻址困难,但插入和删除容易;所以我们将数组和链表结合在一起(即散列表),发挥两者各自的优势 阅读详情

我们在看 HashMap 的源码的时候经常能看到 tab[i = (n - 1) & hash]) 这么一串代码。他是专门用来计算当前 key 存储的位置,并获取当前存储位置的元素,进行后续的判断。

让我们用图的形式更直观的看一下它是如何怎么计算的吧。
123
i = 9 即 tab[9]

这就是 HashMap 的精华所在,不论是 get() 还是 put() 都是通过上述的方法计算当前位置是否存在值或获取当前位置的值。这也是 HashMap 为什么数组的长度都为 2^n 的原因,这种操纵字节的计算方法具有足够的高效性。

所以这段代码 p = tab[i = (n - 1) & hash] 可以理解为,将 hash 的 bit 位截取到 (n - 1) 的 bit 位长度。并找到该字节对映的 node 数组坐标中的值。

也间接的证明的 key 的存储位置和 key 的 hash 低位有着紧密的联系(因为通常情况下,我们的 Map 也不会太大)

相比较而言:但是因为和低位关系紧密,所以造成的碰撞的几率会大很多。对于不同的 key ,如果高位不同的多,低位相同的多,碰撞概率相应的也增加了。

而 HashMap 为了解决这方面问题,用了两个位运算方法将计算出来的 hashCode 通过高位的不同也影响到低位变化,使低位的最终结果是通过高位和低位计算得到的。

    static final int hash(Object key) { 
         int h;
        return (key == null) ? 0 :(h = key.hashCode()) ^ (h >>> 16);
    }

^ 的意思就是位运算中,同一位置两个值相同的为 0 ,不同为的 1

这就可以真正的动一位则动全身。不论高位还是低位,只要有一位不同,计算存储位置相同的概率就会大幅度降低(但是还是有的)。


Map (一) HashMap 构造函数的秘密
Map (二) HashMap put()方法详细解刨
Map (三) HashMap 如何利用 hash 计算存储位置
Map (四) HashMap 已故事的角度理解 resize()
Map (五) HashMap get()

一文弄懂HashMap中所有的位运算,理解HashMap设计的精妙! 大家好,我是春风。hashmap经常会被作为我们面试的热身问题。当你讲完自我介绍,面试官上下翻看着你的简历,余光还瞟一眼你的状态和形象。入定,面试官淡淡的说出:请简单讲一下hashmap?或者你理解的hashMap?其实这种泛泛的问法一般是考验面试者的逻辑能力和表述能力,你是否能有条不紊的讲出hashmap的结构,put大致流程等等,回答时除了流程清晰,我们也可以稍微带一点源码上的理解,来体现我们的深度。当然很多情况下,你自己不体现,那面试官会帮你体现~这就是接下来通常会问的hashmap底层原理了,底层原 阅读详情

相关推荐

HashMap如何确定key的存储位置

将传入的参数 key 调用自身的方法 hashCode() 得到哈希值 h。根据哈希值 h 调用扰动函数 hash() 计算 h ^ (h >>> 16) 得到扰动后的哈希值 hash。根据哈希值 hash 取模操作 hash & (n - 1) 从而确定 key 的存储位置。以上就是本篇文章的全部内容了。

weixin_64403990的博客 442

HashMap存储位置计算

HashMap产生hash碰撞一般说法是key的hashCode值一样,其实这种说法是不严谨的,准确说底层计算下标值一样(废话),当然,key的hashCode的值一样是最明显的原因,而hashCode值不同也会导致hash冲突。 HashMap为了存取高效,要尽量较少碰撞,就是要尽量把数据分配均匀,每个链表长度大致相同,这个实现就在把数据存到哪个链表中的算法; 这个算法实际就是取模,hash...

meser88的博客 2897

散列算法、斐波那契散列

需要注意的是,不同的散列算法具有不同的特点和用途,选择哪种算法取决于具体的应用场景和需求。:当HashMap中的元素数量超过其容量(capacity)的负载因子(load factor,默认为0.75)时,HashMap会进行扩容,即创建一个新的、容量更大的数组,并重新计算所有元素的散列值和新位置。综上所述,乘法散列(或更广泛地说,散列算法中的扩容机制)使用2的幂值作为每次的扩容条件,主要是为了提高效率、保证哈希分布的均匀性、优化内存利用率、简化实现以及平衡空间和时间成本。

猪猪 1699

HashMap

一、数据结构 顺序存储: 性质:连续的存储单元来存储数据(逻辑上连续,物理上也连续) 特点:随机存取。适合查找,不适合增删;更节约空间 链式存储: 性质:非连续的存储单元来存储数据(逻辑上连续,物理上不一定连续) 特点:非随机存取。适合增删,不合适查找;有指针域,空间利用率比顺序存储低 索引存储: 性质:通过增加索引(相当于书的目录),来检索目标,一般使用B+树实现 特点:检索快,插入慢。费空间 延伸:B+树和B-树的最主要区别之一是B+树只有叶子节点才存储data信息,而B-树在其他节点也存储

weixin_44495008的博客 1069

Java面试要点56 - Java HashMap源码解析:哈希算法

在使用自定义对象作为HashMap的key时,正确实现hashCode()和equals()方法是至关重要的。这两个方法需要满足一致性要求,即相等的对象必须具有相同的哈希码。// 正确实现hashCode()方法@Override// 使用不变的字段计算哈希码// 正确实现equals()方法@Overrideif (!User user1 = new User("1001", "张三");User user2 = new User("1001", "张三");

程序媛学姐的博客 580

硬件设计--DC/DC电源芯片详解

本文参考:http://www.elecfans.com/article/83/116/2018/20180207631874.html https://blog.youkuaiyun.com/wangdapao12138/article/details/79763343 第一次写博客,不喜勿喷,谢谢!!! DC/DC电源指直流转换为直流的电源,从这个定义上看,LDO(低压差线性稳压器)芯片也应该属于D...

weixin_30794499的博客 7876

哈希表、Java中HashMap

哈希算法,是一类算法; 哈希表(Hash Table)是一种数据结构; 哈希函数,是支撑哈希表的一类函数; Map是映射、地图的意思,在Java中Map表示一种把K映射到V的数据类型; HashMap是Java中用哈希数据结构实现的Map; 一、Hash算法 1. 是什么? 查词典 先来看英语翻译: hash 英 [hæʃ] 美 [hæʃ] n. 剁...

「有且仅有」 2万+

2022年全球市场微波等离子体CVD反应器总体规模、主要生产商、主要地区、产品和应用细分研究报告

据GIR (Global Info Research)调研,按收入计,2021年全球微波等离子体CVD反应器收入大约 百万美元,预计2028年达到 百万美元,2022至2028期间,年复合增长率CAGR为 %。

MARKETRESEARCH的博客 1137

Map<String,Object> map=new HashMap<String,Object>详解

Map是一个接口,即Interface Map<K,V>,其中K-key类型和V-value的类型 它的每个元素包含一个key对象和一个value对象,且在这两个对象之间存在一种映射的对应关系,所有从Map集合中访问元素时,只有指定了key就可以找到对应的value,因此key必须是唯一的且不能重复,当key相同时,后面的value值会覆盖之前的value值。 Map定义的一些通用的方法 Map接口有很多实现类,如TreeMap,Hashtable,SortedMap,HashMa.

wenchang-的博客 5万+

ICCompiler II学习笔记(一)ICC II使用全流程 overview

学习笔记同步发布在我的个人网站上,欢迎来访查看。 个人学识有限,理解可能有误,仅供参考。 文章目录一、前言二、 ICC II 简介和 GUI2.1 Blocks 和 Design Libraries2.2 Objects2.3 Application Options三、Design Setup四、APR flow五、 课程主题:如何用 ICC II来实现最好的PPA 一、前言 现在的芯片都在追求一个极致的PPA 芯片的生成可以分为以下 5大步骤: Front-end Design:前端设计,最终产生

一名FPGA芯片设计爱好者的技术博客 2万+

NVIDIA Tao Toolkit环境配置踩坑

请搭配食用该文章为 Tao 安装中可能出现的问题进行解答,如果存在本文章中没出现的问题,欢迎提问,由我复现后更新文章。由于大部分云服务器厂商不能支持 docker,因此我使用的环境为2023年5月27日在平台租的 3080 旧版环境进行实验。

qq_36630208的博客 772

Hash函数与算法、哈希查找、哈希冲突解决方法总结

Hash哈希 1.基本概念   Hash,也叫哈希或散列,就是把任意长度的输入(也叫预映射),通过散列算法,变换成固定长度的输出,该输出就是散列值。   若结构中存在和关键字key相等的记录,则必定在H(key)的存储位置上。称该H(key)为哈希函数。   根据设定的哈希函数H(key)和处理冲突方法将一组关键字映射到一个有限的地址区间上,并以关键字在地址区间中的象作为记录在表中的存储位置,这种...

qq_37020594的博客 1万+

NVIDIA GPU任务调度全景:从Block分配到Warp发射

GPU并行计算的核心是任务调度,而CUDA kernel在GPU上的执行并非简单的一次性操作,而是经过从CPU命令队列到硬件前端,再到GigaThread引擎和Warp Scheduler的多层协同。理解这一过程,是性能优化的基础。Warp作为硬件调度的基本单位,其状态切换与延迟隐藏能力直接决定计算单元的利用率;而Occupancy作为衡量SM上活跃Warp池大小的指标,也并非越高越好,需要结合访存模式与资源占用综合判断。对于多任务并发场景,Stream优先级、计算抢占、MIG硬件隔离与MPS软件共享等机制

weixin_32612263的博客 270

java中HashMap与Hash表详解

转载至https://blog.youkuaiyun.com/u010297957/article/details/51974340 哈希算法,是一类算法; 哈希表(Hash Table)是一种数据结构; 哈希函数,是支撑哈希表的一类函数; Map是映射、地图的意思,在Java中Map表示一种把K映...

风雨落 2万+

迟滞电压比较器电路的原理与计算

迟滞电压比较器是一种具有双阈值特性的电路,通过正反馈机制实现抗噪声干扰功能。文章详细分析了其工作原理,包括同相型和反相型两种结构的电压阈值计算与电阻设计方法,并提供了已知门限求电阻和已知电阻求门限的推导公式。工程应用中需注意输出类型匹配、电阻取值范围、噪声裕量设计等问题。该比较器在信号处理、波形转换等场景中具有重要应用价值,设计时需综合考虑供电电压、参考电压和噪声特性等因素。

硬核科技 2683

【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏5(附项目源码,完结)

本期是本项目的最后一篇,主要内容是配置环境、生成不同敌人、结束重开。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2575

js——Set和Map,以及哈希表

1.哈希表 参考链接 哈希表概述: 散列表(Hash table,也叫哈希表),是根据关键值(Key)而直接进行访问的数据结构。也就是说,它通过把关键值key映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数(哈希函数),存放记录的数组叫做散列表。(哈希表一般用数组来存储) 向哈希表中存数据: 根据数据的key值和哈希函数,得到一个数组下标,这个下标的含义是数据在哈希表中的存放的位置。若发生了冲突,则再根据冲突的处理方法来解决冲突。找到最终存放的位置后,将数据存放进去。 在哈希表中查

leilei7407的博客 1万+

PCL 读取和保存点云

PCL (Point Cloud Library) 是一个用于处理 3D 点云数据的开源库。在处理点云数据时,常见的任务包括点云的读写和可视化。PCL 提供了强大的 IO 模块来读取和写入各种格式的点云文件,并且提供了可视化模块来对点云进行渲染和显示。点云的读写与显示是很多 3D 数据处理任务的基础步骤,通过这些步骤,可以对点云进行预处理、分析和操作。

纵马踏花向自由 1739

哈希表(HashMap、HashSet)

是个存储结构:可以让我们一次从表中直接拿到想要的元素,时间复杂度为O(1)为什么能实现O(1):通过哈希(散列)方法,使元素的存储位置和它的关键码之间建立一一映射的关系如果想要存取元素,都是利用哈希(散列)方法 + 关键码,从而计算出index位置,然后进行操作(怎么放的就怎么给它取出来哈希函数示例:此时写着容量是1000,但实际上是2次幂数,容量为1024。

wuweixiaoyue的博客 4145

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

哈希(Hash)算法与查找

哈希算法(Hash)​​,简单来说就是一个“​​数据粉碎机​​”。你给它输入任意内容(文字、文件、密码等),它会吐出一串​​固定长度的乱码​​(叫“哈希值”)。

2302_81240667的博客 2519

android 蓝牙通讯demo

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

HashMap中对hash值的计算

1.同一个对象,在hashMap与TreeMap中的哈希值是一样吗?如何保证hash值的稳定性?2.HashMap的链表长度超过8的时候,会将链表转换成红黑树。但是hashCode分布良好的话,链表的长度符合泊松分布,长度达到8的概率小于千万分之一。hashCode是如何保持分布良好的?使用位运算代替传统的取模运算,加快计算效率将hashCode的高位与地位进行搅动运算,进一步减少哈希冲突。

qq_57865884的博客 1231

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

哈希算法以及哈希表(Hash table,也叫散列表)

hash 英 [hæʃ] 美 [hæʃ] n. 剁碎的食物;混杂,拼凑;重新表述 vt. 搞糟,把…弄乱;切碎;推敲 n. (Hash)人名;(阿拉伯、保、英)哈什;(西)阿什

weixin_59966683的博客 896

深入理解C语言中的哈希算法

深入理解C语言中的哈希算法

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 1404

解密 Rust HashMap:哈希算法与冲突解决的高效之道

有时我们希望在性能敏感的场景(如游戏引擎或嵌入式系统)中牺牲部分安全性换取速度。Rust 允许通过println!("{:?此时,开发者可替换为更快但安全性较低的算法,如 FNV 或 AHash,以满足特定需求。

rui371的博客 950

Rust 中 HashMap 的哈希算法与冲突解

Rust中的HashMap通过哈希表实现高效键值对存储,默认采用SipHash算法防止哈希碰撞攻击。它使用开放地址法和线性探测处理冲突,当负载因子超过0.75时自动扩容优化性能。在多线程环境中,可使用DashMap替代,其分段锁机制实现线程安全并发访问。合理设置初始容量和负载因子能显著提升HashMap性能,理解其底层原理有助于在不同场景下进行优化。

2501_94033047的博客 807

带你了解!哈希?什么是哈希表?什么是哈希算法?

哈希(Hashing),也被叫做散列,它是一种把任意长度的输入数据(比如一段文本、一个文件等)通过特定的哈希函数转换为固定长度输出(通常是数字或字符串)的过程。不过,由于输入的可能性是无穷的,而输出的范围是有限的,所以难免会出现不同输入产生相同输出的情况,这种情况被叫做哈希冲突。​​作用​​:将任意输入(如字符串、对象)转换为固定范围的整数(图中输出为序列标签2,注意不是下标索引,而且索引+1的映射关系)。​​物理结构​​:一个连续的数组(图中索引范围0-4),每个位置称为​​桶(Bucket)​​。

m0_46808930的博客 3208
上一篇: Map (二) HashMap put()方法详细解刨
下一篇: Map (四) HashMap 已故事的角度理解 resize()
Carey丶zsh
博客等级 码龄10年 15粉丝 47原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值