什么是HashMap?

HashMap的自定义实现 文章目录前言一、HashMap是什么?二、代码实现1.01.引入库2.读入数据总结 前言 HashMap是Map集合中的重要组成部分,也是我们在实际编程中经常会使用到的一种数据类型。所以为了学习散列表,我决定对HashMap进行自我重构,同时将我编写的HashMap与系统自带的HashMap进行效率比对。 提示:以下是本篇文章正文内容,下面案例可供参考 一、HashMap是什么? 写代码之前,我们需要先了解一下,什么是HashMap?HashMap的使用场景是什么?这是一个线程安全的类吗?以下我将一一解 阅读详情

来源:微信公众号“程序员小灰”

作者:玻璃猫

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

————————————

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

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


HashMap数组每一个元素的初始值都是Null。

640?wx_fmt=png

对于HashMap,我们最常使用的是两个方法:Get 和 Put。



1.Put方法的原理


调用Put方法的时候发生了什么呢?


比如调用 hashMap.put("apple", 0) ,插入一个Key为“apple"的元素。这时候我们需要利用一个哈希函数来确定Entry的插入位置(index):


index =  Hash(“apple”)

假定最后计算出的index是2,那么结果如下:


640?wx_fmt=png



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

640?wx_fmt=png



这时候该怎么办呢?我们可以利用链表来解决。


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


640?wx_fmt=png

需要注意的是,新来的Entry节点插入链表时,使用的是“头插法”。至于为什么不插入链表尾部,后面会有解释。



2.Get方法的原理


使用Get方法根据Key来查找Value的时候,发生了什么呢?


首先会把输入的Key做一次Hash映射,得到对应的index:


index =  Hash(“apple”)

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

640?wx_fmt=png

第一步,我们查看的是头节点Entry6,Entry6的Key是banana,显然不是我们要找的结果。


第二步,我们查看的是Next节点Entry1,Entry1的Key是apple,正是我们要找的结果。


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



640?wx_fmt=jpeg

640?wx_fmt=jpeg



640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

————————————

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg

之前说过,从Key映射到HashMap数组的对应位置,会用到一个Hash函数:


index =  Hash(“apple”)


如何实现一个尽量均匀分布的Hash函数呢?我们通过利用Key的HashCode值来做某种运算。

640?wx_fmt=jpeg

index =  HashCode(Key) % Length ?

640?wx_fmt=jpeg

如何进行位运算呢?有如下的公式(Length是HashMap的长度):


index =  HashCode(Key) &  (Length - 1) 


下面我们以值为“book”的Key来演示整个过程:

1.计算book的hashcode,结果为十进制的3029737,二进制的101110001110101110 1001。

2.假定HashMap长度是默认的16,计算Length-1的结果为十进制的15,二进制的1111。


3.把以上两个结果做与运算,101110001110101110 1001 & 1111 = 1001,十进制是9,所以 index=9。


可以说,Hash算法最终得到的index结果,完全取决于Key的Hashcode值的最后几位。



640?wx_fmt=jpeg

640?wx_fmt=jpeg

假设HashMap的长度是10,重复刚才的运算步骤:


640?wx_fmt=png

单独看这个结果,表面上并没有问题。我们再来尝试一个新的HashCode  101110001110101110 1011 :


640?wx_fmt=png

让我们再换一个HashCode 101110001110101110 1111 试试  :


640?wx_fmt=png

是的,虽然HashCode的倒数第二第三位从0变成了1,但是运算的结果都是1001。也就是说,当HashMap长度为10的时候,有些index结果的出现几率会更大,而有些index结果永远不会出现(比如0111)!


这样,显然不符合Hash算法均匀分布的原则。


反观长度16或者其他2的幂,Length-1的值是所有二进制位全为1,这种情况下,index的结果等同于HashCode后几位的值。只要输入的HashCode本身分布均匀,Hash算法的结果就是均匀的。


640?wx_fmt=jpeg

(完)

你看到的只是冰山一角, 更多精彩文章,请移步《2016文章精华》或者《2017上半年文章精华》


码农翻身

用故事讲述技术

0.jpeg

HashMap的用法 HashMap是 Java 中的一个非常重要的集合类,它实现了Map接口。HashMap存储键值对(key-value pairs),其中每个键都是唯一的,并且映射到最多一个值。HashMap允许使用null值和null键,但需要注意的是,HashMap最多只能有一个null键。 阅读详情

相关推荐

一篇搞懂HashMap,手写HashMap

手撕HashMap

wayhb的专栏 1822

什么是hashmap

众所周知,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。 HashMap数组每一个元素的初始值都是Null。 对于HashMap,我们最常使用的是两个方法:Get 和 Put。 1.Put方法的原理 调用Put方法的时候发生了什么呢?

不生产代码_代码的搬运工的博客 6931

前端开源库-hashmap

前端开源库-hashmaphashmap,用于javascript的hashmap类

HashMap(整理)

HashMap底层是由散列表实现的。 由此首先介绍散列表 1、散列表 数组是具有相同的数据类型且按一定次序排列的一组变量的集合体,数组在内存中的地址是连续的。 优点 随机访问性强(通过下标进行快速定位) 查找速度快 缺点 插入和删除效率低(插入和删除需要移动数据) 可能浪费内存(因为是连续的,所以每次申请数组之前必须规定数组的大小,如果大小不合理,则可能会浪费内存) 内存空间要求高,必须有足够的连续内存空间。 数组大小固定,不能动态拓展 链表内存地址是散列、不连续的。 数组静.

luott_777的博客 604

从零构建物联网监控系统:STM32+迪文屏+WiFi模组的实战解析

本文详细解析了基于STM32微控制器、迪文串口屏和WiFi模组构建物联网监控系统的完整方案。从硬件选型、系统架构设计到数据交互实现,提供了包括迪文屏GUI开发、STM32通信协议、低功耗优化等实战经验,帮助开发者快速掌握物联网监控系统的核心技术。

docker7nomad的博客 731

badusb详细制作教程(两种方式实现远控)

badusb是一种几乎可以突破任何杀毒软件和防火墙的设备,堪称渗透测试利器 文章目录前言一、什么是badusb?二,badusb的优点三,badusb是如何攻击的?badusb原理HID攻击漏洞产生原因三、准备步骤1.设备2,编辑器的安装与设置四,编写代码(重点)第一种: SEToolkit + badusb实现PowerShell注入攻击第二种:Cobalt Strike + badusb 实现PowerShell注入攻击五,烧录六,badusb有多强大攻击场景总结 BadUSB是《黑客军团》中

Ghost_system的博客 1万+

什么是HashMap?什么情况下使用HashMap?

这里是修真院后端小课堂,每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析后端知识/技能,本篇分享的是: 【什么是HashMap?什么情况下使用HashMap?】 大家好,我是IT修真院深圳分院第十一期学员,一枚正直纯洁善良的JAVA程序员。 今天给大家分享一下,修真院官网JAVA任务十的一个知识点:什么是...

IT修真院:初学者转行到互联网的聚集地 7641

yolov5部署之七步完成tensorRT模型推理加速

目录前言step 1. 下载yolov5源码以及tensorrtx源码,并将yolov5s.pt转为.wts模型step 2. 确定并下载自己准备使用的CUDA版本。step 3. 根据自己的CUDA版本下载对应版本的cuDNN以及TensorRTstep 4. 根据自己使用的VS版本下载对应版本的OpenCVstep 5. 安装CUDAstep 6. 安装cuDNN、TensorRT以及验证TensorRT是否安装成功 前言     前段时间研究了Pytorch的环境配置,之后便从github上下载了yo

Christo的博客 4万+

【HashMap】

HashMap简单概括

weixin_52553065的博客 2087

华为OD机试新系统真题-魔法咒语组合(Java/Py/C++/Go/C/Js)

华为OD机试 新系统真题【魔法咒语组合】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题【魔法咒语组合】多语言题解

qq_45776114的博客 671

MATLAB计算干旱指标:SPI、SRI、SWAP、DWAAI、EDI等

简介各种干旱指数以及其MATLAB代码实现

WW、forever的博客 2万+

HashMap相关面试题(哈希表、HashMap的实现原理、HashMap的put方法的具体流程、HashMap的扩容机制、HashMap的寻址算法)

HashMap相关面试题(哈希表、HashMap的实现原理、HashMap的put方法的具体流程、HashMap的扩容机制、HashMap的寻址算法)

聂可以的博客 2249

2026年OPPO嵌入式岗位面试题带详细答案

本文总结了OPPO嵌入式岗位面试的核心考点,涵盖硬件驱动、系统启动、Linux内核开发等7大模块共34道典型题目。重点解析了SPI通信协议、中断处理、U-Boot启动流程、Linux驱动开发等关键技术,突出硬件调试与工程实践能力考核。题目设置贴合实际岗位需求,适合校招与社招驱动开发岗位应聘者系统复习,帮助掌握嵌入式开发的核心知识与面试要点。

Open 492

详解 HashMap扩容机制,HashMap的底层原理以及HashSet在底层原理

利用HashCode方法和equals方法HashCode方法来计算出哈希值,根据哈希值计算机出要元素要存入的位置,然后再调用equals方法比较对象内部的属性值是否一样利用什么机制保证去重?**利用HashCode方法和equals方法HashCode方法来计算出哈希值,根据哈希值计算机出要元素要存入的位置,然后再调用equals方法比较对象内部的属性值是否一样。

Java技术加油站的博客 2112

零基础入门转录组数据可视化——绘制差异小提琴图(常规)

转录组数据可视化之一,先介绍相关基础知识,其次用实际案例为基础,由浅入深介绍差异小提琴图绘制的全过程,包括内容有相关代码和截屏。

呆猪儿的博客 638

YOLO26 数据标注工具:LabelImg、Label Studio实战指南:主流标注工具的安装配置与使用技巧,高效完成目标检测数据标注

本文介绍了目标检测中数据标注的核心地位与常用工具。数据标注质量直接影响模型性能,需要关注准确性、一致性等维度。文章详细讲解了边界框、类别标签等基本概念,并对比了LabelImg、Label Studio等主流标注工具的特点。重点介绍了LabelImg的轻量级、易用性等优势,以及Label Studio的协作功能,为不同规模项目提供标注工具选择建议。

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 1178

HashMap详解

本文主要介绍了Java集合框架中HashMap的相关知识,包括源码分析、hash 原理、扩容机制、加载因子、线程不安全等内容。

专注Java和MySQL领域知识分享 1687

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

HashMap深入讲解

摘要: HashMap是Java中基于哈希表的Map实现类,允许null键值且不保证顺序。其底层采用数组+链表/红黑树结构,默认容量16,负载因子0.75(平衡空间与时间效率)。HashSet实际通过HashMap实现。关键特性包括:key需重写equals()和hashCode(),value需重写equals();当链表长度>8且数组容量≥64时转为红黑树。put操作先计算key的hash值(通过hashCode()高16位异或),再处理哈希冲突。构造方法可自定义初始容量和负载因子。

1360

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

面试手写HashMap,手撕HashMap

前言: 现在面试时,面试官经常会问到HashMap,简单点就会问下HashMap的一些关键知识点,困难些的可能会当场让你手写一个HashMap,考察下你对HashMap底层原理的了解深度;所以,今天特别手写了一个简单的HashMap,只实现了 put、get、containsKey、keySet 方法的 HashMap,来帮助我们理解HashMap的底层设计原理。 本文...

木子雷的博客 2220

JAVA之HashMap详解

HashMap 基于哈希表的 Map 接口实现,是以 key-value 存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的 key、value 都可以为 null,此外,HashMap 中的映射不是有序的。jdk1.8 之前 HashMap 由数组 + 链表组成,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突(两个对象调用的 hashCode 方法计算的哈希值经哈希函数算出来的地址被别的元素占用)而存在的(“拉链法”解决冲突)。

励志成为一名优秀的全能型软件开发工程师。 2328

HashMap 详解

本文深入解析Java中HashMap的核心特性、底层数据结构及哈希冲突处理机制,涵盖自定义类型作为key的处理、手写HashMap实现及Java8后的优化,通过源码分析揭示哈希表扩容与性能优化策略,助你掌握高效数据管理与操作技巧。

m0_73941339的博客 1423

HashMap

如果这和个位置上有多个元素,还需要用key的equals方法在对应位置的链表中找到需要的元素,通常equals方法一般都会根据实际的业务内容来定义。这里适用位运算,所以上面的capacity要是2的次方,因为2的次方减1得到一个全1的二进制数,做and操作就会保证索引的均匀性,否则加入某一位是0,那么这一位就永远不会在索引中出现。如果key为null,会存放在索引为0的entry,但是这个entry不一定只有key为null的value,所以需要遍历所有的entry,返回key为null的value。

weixin_43991255的博客 863

HashMap原理

HashMap是基于哈希表的键值对存储结构,采用数组+链表+红黑树解决哈希冲突。核心通过键的hashCode计算哈希值,使用(n-1)&hash确定数组索引位置。默认容量16,负载因子0.75,超过阈值会扩容2倍。Java8优化了哈希扰动函数,将高16位与低16位异或,使分布更均匀。当链表长度超过8且数组容量≥64时,链表转为红黑树;节点数低于6时转回链表。put方法先检查桶是否为空,为空则直接插入;否则处理冲突,匹配则更新,不匹配则链式存储或树化。

猫狗鼠鱼的储物间 1096

Java HashMap

HashMap 的 key 与 value 类型可以相同也可以不同,可以是字符串(String)类型的 key 和 value,也可以是整型(Integer)的 key 和字符串(String)类型的 value。如果你只想获取 key,可以使用 keySet() 方法,然后可以通过 get(key) 获取对应的 value,如果你只想获取 value,可以使用 values() 方法。对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hashMap 中。

2401_88984449的博客 1101

HashMap、创建并遍历HashMap集合、LinkedHashMap

HashMap是基于哈希表的Map实现。键是哈希表结构,可以保证键的唯一性。 HashMap 继承于AbstractMap,实现了Map接口。 HashMap的设计初衷主要是为了解决键值(key-value)对应的关联的,HashMap的优势是可以很快的根据键(key)找到该键对应的值(value)。注意一下,HashMap是一种无序的存储结构。 遍历 1.案例1 键String类型,值S...

元气满满晨 1万+
上一篇: Java帝国之观察者模式
下一篇: 90后“老头儿”和00后Go小子的硬盘夜话
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值