HashMap:理解Hash、底层实现与扩容机制

 391e6864637549bdbe7d46301c1d559c.png

一、简单叙述

HashMap是Java中常用的一种数据结构,它以键值对的形式存储数据,具有高效的查找、插入和删除操作。本文将详细介绍HashMap的底层实现原理,包括哈希技术、底层数据结构和扩容机制,帮助读者深入理解HashMap的工作原理。

HashMap是Java集合框架中的一部分,它基于哈希表实现,允许使用任何对象作为键来存储和检索值。HashMap是非同步的,如果多个线程同时访问并至少有一个线程修改了HashMap,则必须在外部同步。

底层实现

​
public class HashMap<K, V> {static class Node<K, V> {final int hash;final K key;V value;Node<K, V> next;Node(int hash, K key, V value, Node<K, V> next) {this.hash = hash;this.key = key;this.value = value;this.next = next;}}// 其他代码...
}​

 

二、哈希技术

  1. 哈希函数

哈希函数是一种将任意长度的数据映射为固定长度数据的算法。在HashMap中,哈希函数的作用是将键映射到一个索引位置,以便快速查找和存储键值对。

  1. 哈希冲突

当两个或多个键的哈希值相同时,它们将映射到同一个索引位置,这种现象称为哈希冲突。HashMap使用链表和红黑树来解决哈希冲突,确保每个索引位置只存储一个键值对。

三、HashMap的底层实现

  1. 数据结构

HashMap底层采用数组+链表+红黑树的数据结构实现。数组是HashMap的主体,用于存储键值对;链表用于解决哈希冲突;红黑树是在链表长度超过一定阈值(默认为8)时,将链表转换为红黑树,以提高查找效率。

  1. 存储结构

HashMap的存储结构是一个Node类型的数组,Node是一个内部类,实现了Map.Entry接口。每个Node对象包含四个属性:key(键)、value(值)、hash(哈希值)和next(指向下一个Node的指针)。当发生哈希冲突时,新的键值对将被添加到链表中。

四、扩容机制

  1. 什么时候扩容

当HashMap中的元素数量达到数组大小的加载因子(默认为0.75)时,会触发扩容操作。加载因子是一个阈值,用于控制数组的大小和扩容的时机。加载因子越大,数组的空间利用率越高,但冲突的概率也越大;加载因子越小,数组的空间利用率越低,但冲突的概率也越小。因此,选择合适的加载因子可以平衡空间利用率和冲突概率。

  1. 如何扩容

扩容操作包括两个步骤:创建新的数组和重新计算键的哈希值。首先,HashMap会创建一个新的数组,其大小是原数组大小的两倍。然后,HashMap会遍历原数组中的每个元素,重新计算键的哈希值,并将键值对存储到新的数组中。在重新计算哈希值时,HashMap会使用一个特殊的算法来确保相同的键在新的数组中仍然具有相同的哈希值。这个算法称为“再哈希”。

​
void resize(int newCapacity) {Node<K, V>[] oldTable = table;int oldCapacity = oldTable.length;if (oldCapacity == MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE;return;}Node<K, V>[] newTable = new Node[newCapacity];transfer(newTable);table = newTable;threshold = (int) (newCapacity * loadFactor);
}​

 

五、总结

本文详细介绍了HashMap的底层实现原理,包括哈希技术、底层数据结构和扩容机制。HashMap是一种高效的数据结构,它使用哈希表实现键值对的存储和检索操作。通过深入了解HashMap的工作原理,我们可以更好地理解和使用它来解决实际问题。在实际开发中,我们需要根据具体情况选择合适的加载因子和初始容量来创建HashMap实例以提高性能和效率。

 

参考文章

谈谈我对HashMap扩容机制的理解及底层实现-CSDN博客

 

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

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

相关文章

Java IO 模型之 BIO、NIO、AIO 详解

目录 一. 前言 二. IO 模型 2.1. IO 模型分类 2.2. BIO、NIO、AIO 使用场景分析 2.3. NIO 和 BIO 的比较 三. BIO&#xff08;同步阻塞&#xff09; 3.1. BIO 编程流程 3.2. BIO 应用实例 3.3. 问题分析 四. NIO&#xff08;同步非阻塞&#xff09; 4.1. 基本介绍 …

Dubbo 3.x源码(13)—Dubbo服务发布导出源码(2)

基于Dubbo 3.1&#xff0c;详细介绍了Dubbo服务的发布与引用的源码。 此前我们学习了Dubbo 3.x源码(12)—Dubbo服务发布导出源码(1)&#xff0c;也就是Dubbo服务发布导出的入口源码&#xff0c;现在我们继续学习&#xff0c;服务导出的核心方法doExportUrls的源码。 Dubbo 3.x…

一文读懂Java中的设计模式——单例模式!默认情况下,Spring的Bean就是单例的

单例模式概念 单例模式确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个系统提供这个实例。单例模式只应在有真正的“单一实例”的需求时才可使用。总结起来单例模式有三个优点&#xff1a; 全局访问共享资源&#xff1a;当需要在应用程序的多个地方共享和使用相…

跑代码中遇到的错误合集(持续更新)

1.TypeError: dropout(): argument ‘input‘ (position 1) must be Tensor, not str 原因&#xff1a;dropout函数接收到的参数是一个字典类型(需手动设置其不要返回字典类型) 解决步骤: 1.根据代码定位到dropout函数 2.定位到函数中的参数 3.对给dropout函数参数赋值的函数的…

[渗透测试学习] Sau - HackTheBox

首先是信息搜集&#xff0c;nmap扫一下 nmap -sV -sC -p- -v 10.10.11.224 发现存在两个端口&#xff0c;55555端口有http服务&#xff0c;访问一下 获得线索request-baskets版本为1.2.1&#xff0c;搜索发现存在漏洞 那么我们试试构造ssrf&#xff0c;create的时候bp抓包 构…

定时器TIM HAL库+cubeMX(上)

定时器时钟源APB1 36MHz 一.基本定时器 1.基本框图 2.溢出时间计算 3.配置定时器步骤 TIM_HandleTypeDef g_timx_handle;/* 定时器中断初始化函数 */ void btim_timx_int_init(uint16_t arr, uint16_t psc) {g_timx_handle.Instance TIM6;g_timx_handle.Init.Prescaler p…

【数据安全】金融行业数据安全保障措施汇总

数字化的今天&#xff0c;数据的价值不可估量&#xff0c;尤其是金融行业&#xff0c;数据不仅代表着企业的核心资产&#xff0c;还涉及到客户的隐私和信任。因此对于金融行业而言&#xff0c;保障数据安全至关重要。下面我们就来一起讨论为什么金融行业要保障数据安全&#xf…

web界面请求过程

一、计算机获取IP&#xff08;DHCP协议&#xff09;&#xff1a; 计算机生成DHCP报文&#xff0c;并将此报文放入UDP报文段中&#xff08;源端口68&#xff0c;目的端口67&#xff09;&#xff0c;此UDP报文段被放入IP数据报中&#xff08;广播IP目的地址:255.255.255.255,源I…

Idea执行bat使用maven打包springboot项目成docker镜像并push到Harbor

如果执行以下命令失败&#xff0c;先把mvn的-q参数去掉&#xff0c;让错误输出到控制台。 《idea配置优化、Maven配置镜像、并行构建加速打包、解决maven打包时偶尔几个文件没权限的问题》下面的使用company-repo私有仓库和阿里云镜像仓库同时使用的配置参考。 bat echo off …

Linux学习教程(第十二章 Linux系统管理)一

第十二章 Linux系统管理&#xff08;进程管理、工作管理和系统定时任务&#xff09;&#xff08;一&#xff09; 很多人一看本章要学习系统管理了&#xff0c;策一感觉就是"虽然不知道你在说什么&#xff0c;但是看起来很高端"。 其实&#xff0c;系统管理只是一个统…

要实现长页面滑动到指定位置触发动画效果(亲测有效)

1.添加触发动画的元素&#xff1a;在你的 HTML 文件中&#xff0c;将需要触发动画的元素添加相应的类名<div class"animation"> <p>安全工矿 智能工矿 安全工矿 智能工矿</p> </div> 给一个 <div> 元素添加 .animation…

JVM 详解(JVM组成部分、双亲委派机制、垃圾回收算法、回收器、回收类型、了解调优思路)

目录 JVM 详解&#xff08;JVM组成部分、双亲委派机制、垃圾回收算法、回收器、回收类型、了解调优思路&#xff09;1、概念&#xff1a;什么是 JVM ?JVM 的作用&#xff1f; 2、JVM 的主要组成部分&#xff1f;类加载器&#xff08;Class Loader&#xff09;&#xff1a;简单…

02基于matlab的卡尔曼滤波

基于matlab的卡尔曼滤波&#xff0c;可更改状态转移方程&#xff0c;控制输入&#xff0c;观测方程&#xff0c;设置生成的信号的噪声标准差&#xff0c;设置状态转移方差Q和观测方差R等参数&#xff0c;程序已调通&#xff0c;需要直接拍下。

集成数据保护,为您的混合多云环境提供全方位保护

集成数据保护&#xff0c;为您的混合多云环境提供全方位保护 担心数据可用性和数据恢复问题&#xff1f;现在是时候评估您管理混合云基础架构的方式了。NetApp 可以帮助您在整个混合云中抵御计划外中断和数据丢失&#xff0c;并协调响应和恢复……所有这些都不会降低性能。 为…

Vue学习计划-Vue2--VueCLi(五)全局事件总线、消息订阅与发布(pubsub)

抛出问题:我们多级组件&#xff0c;或者任意不想关的子组件如何传递数据呢&#xff1f; 1. 全局事件总线&#xff08;$bus&#xff09; 一种组件间通信的方式&#xff0c;适用于任意组件间通信 全局事件总线示意图&#xff1a; 安装全局事件总线&#xff1a; new Vue({..…

数据结构和算法-图的基本概念及邻接矩阵法和邻接表法和十字链表法和链表链表法

文章目录 图的概念总览图的定义图逻辑结构的应用无向图和有向图简单图和多重图顶点的度&#xff0c;入读&#xff0c;出度顶点-顶点的关系描述连通图&#xff0c;强连通图研究图的局部-子图无向图有向图 连通分量强连通分量生成树生成森林边的权&#xff0c;带权图/网几种特殊形…

虚幻学习笔记15—C++和UI(一)

一、前言 在C可以直接创建按钮、滚轮等UI&#xff0c;并且可以直接绑定并处理响应事件。在创建C代码后还是需要通过蓝图来显示到应用中&#xff0c;总体来说还是不如直接用蓝图来的方便。 本文使用的虚幻引擎为5.2.1。 二、实现 2.1、创建UUserWidgetl类型的C类 声明两个按钮…

java:解决SPI机制遇到的非典型问题-ServiceLoad.load(Class<T> service)方法失效

Java SPI 的实现原理并不复杂&#xff0c;它的实现基于 Java 类加载机制和反射机制。 当使用 ServiceLoader.load(Class<T> service) 方法加载服务时&#xff0c;会检查 META-INF/services 目录下是否存在以接口全限定名命名的文件。如果存在&#xff0c;则读取文件内容&…

uniCloud(一) 新建项目、初始化服务空间、云对象访问测试

一、新建一个带有unicloud 二、创建一个服务空间 1. 右键uniCloud&#xff0c;关联云服务空间 我当前没有服务空间&#xff0c;需要新建一个服务空间&#xff0c;之后将其关联。初始化服务空间需要的时间有点长 服务空间初始化成功后&#xff0c;刷新HBuilder&#xff0c;勾选…

Linux系统下CPU性能问题分析案例

&#xff08;上&#xff09; 本文涉及案例来自于学习极客时间专栏《Linux性能优化实战》精心整理而来&#xff0c;案例总结不到位的请各位多多指正。 某个应用的CPU使用率居然达到100%&#xff0c;我该怎么办&#xff1f; 分析过程 使用观察系统CPU使用情况&#xff08;并按下…