问HashMap底层原理?

news/2025/9/17 15:48:39/文章来源:https://www.cnblogs.com/Mistiest/p/19096920

HashMap是基于数组+链表+红黑树的哈希表。用于存储键值对。

1.哈希计算和扰动处理,也就是Hash方法

每一个Object都有一个 .hashCode 方法。

  1. (哈希计算)在对hashmap进行插入和查询时,先调用key键的key.hashCode()方法获取一个未处理的int哈希值,在底层代码中该值被复制给变量h
  2. (扰动处理)通过异或运算,也就是一位一位比较,如果不同就是1,如果相同就是0。h^(h>>>16)>>>无符号右移操作符,它会将 h 的二进制表示向右移动 16 位,高位用 0 填充,这样就可以将高位的信息混入低位,让哈希值在低位也均匀分布,减少碰撞。

2.索引定位

在原来手动计算的时候,我们是通过取模运算来确定的。在底层是通过(n-1)&hash计算哈希桶bucket下标,效率比取模更高。(原理)

为什么用这个公式?

  1. n-1,在进行了2^n-1后,低位全是1,高位全是0。变成了低位全1的掩码。
  2. 取模运算是算数运算,位运算是底层硬件级操作。且hash&(n-1)hash%n结果完全一样
  3. 20%16=4,20=00010100,20&15=00000100=4

​ 00001111

3.冲突处理

  1. 如果桶的位置为空直接放入新大街店
  2. 如果存在节点,就逐个比较,如果equals()相等就覆盖value,否则追加到链表尾部
  3. 当单个桶中的节点数查过8且数组容量>=64,链表会转换成红黑树来降低最坏复杂度O(log n)

4.扩容机制

  • 默认初始数组长度是16,负载因子是0.75
  • 当元素超过阈值,数组扩容两倍,并重新分配节点位置
  • 扩容后的新下标计算不是不是重新算hashCode,而是用(node.hash&oldCap)判断要留在原位置还是移动到原位置+oldCap。如果端出来的数值是0就放到相应原位置,否则放到原数组长度+目前索引的位置。(原理)
  • )HashMap扩容时,node.hash & oldCap的作用是快速确定节点在新数组中的位置。由于oldCap是2的幂次方,其二进制只有一位为1,其余全为0,因此按位与运算的结果仅由节点哈希值中与该位对应的那一位决定——若该位为0,结果为0,节点在新数组中的位置与原位置相同;若该位为1,结果等于oldCap,节点新位置则为原位置加上oldCap。这种设计的巧妙之处在于,每次扩容都以2倍增长(保持2的幂次方),使得oldCap的二进制独有的1位会左移一位,刚好对应新容量比旧容量多出的判断位,通过一次简单的位运算就能完成节点分流,大幅提升扩容效率。
if((node.hash&oldCap)==0)-->放到newTable[i]
else 						放到newTable[i+oldCap]

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

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

相关文章

用 Go 重写 adbkit:原理、架构与搭建实践

用 Go 重写 adbkit:原理、架构与搭建实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !impor…

C语言环境搭建之Linux子系统使用vscode连接子系统

安装准备工作查看当前系统版本确保高于16215.0开启WSL Windows Subsystem for Linux(简称WSL)是一个为在Windows 10上能够原生运行Linux二进制可执行文件(ELF格式)的兼容层。安装步骤微软商城Microsoft Store安装Ubuntu(本人安装的版本是22.04)点击等待安装完成输入用户名跟…

移远AT指令笔记

# 测试 AT - 测试AT指令功能是否正常# 模块相关 ATI - 查询模块信息 AT+CGMI - 查询模块制造商标识 AT+CGMM - 查询模块型号 AT+CGMR - 查询模块固件版本号# 网络相关 AT+QCCID - 查询集成电路卡识别码(ICCID) AT+GSN …

Chromium历史版本下载方式

首先,访问 https://chromiumdash.appspot.com/branches此链接,点击将要下载的chromium版本。我们点击想要下载的版本的Chromium列,这里我们以137为例。点击此处。会打开https://chromium.googlesource.com/chromium/src.git/+log/refs/branch-heads/7151网页。点击上图红框处…

【ACM出版】第三届物联网与云计算技术国际学术会议 (IoTCCT 2025)

第三届物联网与云计算技术国际学术会议(IoTCCT 2025)将于‌2025年9月26-28日‌在中国海口市盛大召开!【ACM独立出版 | 往届会后四个月EI检索! 】 【IEEE Fellow助力,行业内精彩报告!】 第三届物联网与云计算技术国际学术会议 (IoTCCT 2025) 2025 3rd International Confe…

2025年最全 Wiki 管理工具测评:ONES、Confluence、Notion......哪个更适合你?

随着技术和团队规模的不断发展,如何有效管理知识、文档和任务,成为了研发团队面临的重要挑战。Gartner 发布的《Top Strategic Predictions for 2024 and Beyond》报告指出,成功的研发领导者应该采用新的方法,构建数字化的研发生态系统,利用技术工具创造一个高绩效的研发环…

天下拍拍卖系统:二方系统也能扩展三方平台功能

过去很多年,大多数拍卖公司为了快速开展线上拍卖会,普遍选择入驻阿里拍卖、京东拍卖、公拍网等三方平台——功能齐全、流量大、上线快。但随着业务深入,企业逐渐发现三方平台存在一些限制,想要私有化搭建一套属于拍卖公司自己的拍卖系统,但同时可能也想保留一些三方平台的…

express使用redis

我用的pnpm pnpm add express redisconst express = require(express); const redis = require(redis); var app = express() var port = 3000 // 创建 Redis 客户端实例 const redisClient = redis.createClient({url: redis://172.17.0.185:6379 ,password: b7371d927aec647d…

day07 课程

day07 课程课程:https://www.bilibili.com/video/BV1o4411M71o?spm_id_from=333.788.videopod.episodes&p=148 7.1 字典的应用场景7.2 创建字典的语法7.3 字典常用操作之新增7.4 字典常用操作之删除7.5 字典常用操作之修改———————————————————————…

排序实现java - 教程

排序实现java - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 14p…

.net core 发布到 iis 步骤

1. 打开服务器管理器,管理,添加角色和功能,把 IIS 相关的全勾上。 2. 安装.net core 环境,需要 ASP.NET Core 运行时的 Hosting Bundle 版本,其他版本没用。 3. 安装 webdeploy, 服务器防火墙打开8172端口。 4. 在 IIS 上创建站点, 配置的文件夹权限需要添加 everyone 的…

kylin SP2安装mysql8.4.5

环境:OS:kylin SP2mysql:8.4.5 glibc2.17,建议安装glibc.2.28版本 查看系统glibc版本[root@localhost soft]# ldd --version ldd (GNU libc) 2.28 Copyright (C) 2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There i…

微信社群机器人接口

微信个人号开发API/文档/教程 大家一般需求点无非是以下几个需求: 1.开发个人微信营销系统 2.开发自定义的微信机器人, 3.开发微信智能聊天客服系统 4.定制行业内的群数据分析功能需求很简单,业务代码贼好撸,但是如何和微信交互呢,如何取到微信数据调用相关聊天接口呢,具体…

C++的枚举类

语法:enum class 枚举类名 [: 底层类型] {枚举值1,枚举值2,... };一般形式(当然我们一般默认成员都显转int,因此底层类型一般不写) C++的枚举类: 在C++中,enum class是一种类型安全的枚举类型,它比传统的enum类型提供了更好的作用域控制和类型安全性。使用enum class可以…

Revit二次开发 钢筋生成API(一)

1、自由钢筋生成API创建不受约束的自由形式钢筋。以后不能将约束添加到此钢筋。public static Rebar CreateFreeForm(Document doc,RebarBarType barType,Element host,IList<CurveLoop> curves,out RebarFreeFormValidationResult error )通过此方法,可以创建一个或者多…

方法

什么是方法 方法是程序中最小的执行单位 实际开发中:重复的代码,具有独立功能的代码可以抽取到方法当中 实际开发中方法的好处:可以提高代码的复用性 提高代码的可维护性 最简单的方法定义和调用 方法的格式:把一些代码打包在一起,用到时候就调用 方法定义:把一些代码打包在…

详细介绍:PHP基础-语法初步(第七天)

详细介绍:PHP基础-语法初步(第七天)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !importan…

如何通过Python SDK 删除 Collection

本文介绍如何通过Python SDK删除一个已创建的Collection。 重要 删除Collection后,该Collection所有数据将删除且不可恢复,请谨慎操作。 前提条件已创建Cluster:创建Cluster已获得API-KEY:API-KEY管理已安装最新版SDK:安装DashVector SDK接口定义 Python示例: Client.del…

Inventor Professional 2026.1.1 产品设计与工程制图

描述 Autodesk Inventor提供了专业级机械设计、文档编制和产品仿真工具。参数化建模、直接建模、自由形状建模和基于规则的设计功能的强大组合。用于钣金、结构件设计、三维布管、电缆和线束、演示、渲染、仿真、机床设计等的集成工具。值得信赖的 DWG™ 兼容性,强大的基于模型…