HashMap的详细解读
HashMap是Java语言中的一个重要数据结构,它实现了Map接口,允许我们存储键值对,并且可以根据键直接访问对应的值。
特性
- 键值对存储:HashMap存储的是键值对数据,可以方便的通过键来获取值。
- 无序:HashMap中的元素没有顺序,每次输出的顺序都可能不一样。这是因为HashMap内部是通过哈希表来实现的,元素存储在哈希表中,其位置取决于键的哈希值。
- 允许null键和null值:HashMap允许一个null键和一个null值。
- 扩容:当HashMap中的元素数量达到一定的阈值(默认是桶(bucket)的个数,每个桶是一个链表或者红黑树)时,会进行扩容,扩容会导致原有的数据重新计算哈希值并重新放置
HashMap的工作原理
HashMap的工作原理主要涉及以下几个部分:
- 哈希函数:当我们将键值对插入到HashMap中时,HashMap会使用哈希函数(hash function)将键(key)转换成一个哈希码(hash code),这个哈希码用来确定键值对应该放在哪个桶(bucket)中。
- 桶和链表:在HashMap中,每个桶都是一个链表,链表中的每个节点都包含一个键值对。如果多个键哈希到同一个桶,那么这些键值对就会在链表中顺序存储。
- 扩容和再哈希:当某个桶中的链表长度超过一个阈值(例如8)时,HashMap会将这个桶拆分成两个或更多的桶,这个过程就叫做扩容。扩容会使得HashMap的内部数据结构发生变化,可能会导致查询性能下降。
- 红黑树:当某个桶中的链表长度超过一定阈值(例如16)时,链表会转化成红黑树以提高查询效率。
源码
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { // 其他常量 /** * The default initial capacity - MUST be a power of two. */ static final int DEFAULT_INITIAL_CAPACITY = 16; /** * The load factor used when none specified in constructor. */ static final float DEFAULT_LOAD_FACTOR = 0.75f; /** * The table, resized as necessary. Length MUST Always be a power of two. */ transient Node<K,V>[] table; /** * The number of key-value mappings contained in this map. */ transient int size; /** * The next size value at which to resize (capacity * load factor). */ transient int threshold; /** * The load factor for the hash table. When the capacity is multiplied by * this factor, it is incremented. */ transient float loadFactor; // 其他变量和方法
}
其中,HashMap的核心是它的哈希表(由table数组实现),每个元素都是一个Node对象,其中包含键值对。HashMap还维护了一些其他变量,如size(映射数量)、threshold(下一次扩容的阈值)和loadFactor(哈希表的加载因子)。
HashMap的主要方法包括:构造函数、put(插入键值对)、get(获取键对应的值)、remove(删除键值对)、isEmpty(判断是否为空)等。其中,put和get方法是HashMap中最常用的方法,它们的实现涉及到哈希表的查找和插入操作。以下是put方法的源码:
public V put(K key, V value) { return putVal(hash(key), key, value, false, true);
} final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) { // ①如果哈希表为空,将当前元素插入到第一个位置。p为null。则直接在第一个位置插入元素。同时n++。 tab[i] = new Node<>(hash, key, value, null); // 创建新的节点插入到哈希表中。同时n++。如果超过阈值,则进行扩容。并重新计算哈希值和位置。并将元素插入到新的位置中。同时n++。如果超过阈值,则进行扩容。并重新计算哈希值和位置。
}}
如果哈希表已经满了,那么会进行扩容,即创建一个新的哈希表,大小是原来的两倍,并将原来哈希表中的所有元素重新插入到新的哈希表中。扩容会导致性能的损失,因为每次插入操作都需要重新计算元素的哈希值和位置。因此,在设计HashMap时,需要考虑哈希表的大小和加载因子,以平衡性能和内存使用。
在插入元素时,如果哈希表中已经存在相同的哈希值,那么会进行冲突处理。HashMap采用链表或红黑树来处理冲突。当冲突发生时,会将当前元素插入到链表的尾部或红黑树的叶节点上。当链表的长度超过一定阈值(如8)时,会将链表转换为红黑树,以提高查询效率。
在查询元素时,HashMap会根据给定的键计算出哈希值,并找到对应的桶。然后,在该桶中查找链表或红黑树,直到找到对应的元素或到达链表的尾部或红黑树的叶节点。如果找不到指定的元素,则返回null。
总之,HashMap是一种高效的键值对存储数据结构,通过哈希表实现了O(1)时间复杂度的插入、删除和查询操作。但是,由于哈希表的不确定性,HashMap不支持线程安全。如果需要线程安全,可以使用ConcurrentHashMap或者通过Collections.synchronizedMap方法将Map包装为线程安全。
除了基本的操作,HashMap还提供了其他一些有用的方法,例如:
- containsKey(Object key):判断指定键是否在Map中,存在则返回true。
- containsValue(Object value):判断指定值是否在Map中,存在则返回true。
- get(Object key):返回指定键对应的值,如果键不存在则返回null。
- putAll(Map<? extends K,? extends V> m):将指定Map中的所有映射复制到此Map中。
- remove(Object key):移除指定键及其关联的值。
- size():返回Map中键-值映射关系的数量。
- isEmpty():测试此Map是否为空。
- keys():返回包含此映射中所有键的迭代器。
- values():返回包含此映射中所有值的迭代器。
- entrySet():返回包含此映射中所有映射关系的Set视图。
此外,HashMap还提供了其他一些参数来控制其行为,如初始容量、加载因子等。可以通过构造函数或者相关方法来设置这些参数。
总之,HashMap是一个非常实用的数据结构,适用于需要快速查找和插入键值对的情况。但是,需要注意的是,由于HashMap的不线程安全性,如果在多线程环境下使用,可能会导致数据的不一致性问题,需要使用线程安全的数据结构或者通过Collections.synchronizedMap方法进行包装。
相关文章:
HashMap的详细解读
HashMap是Java语言中的一个重要数据结构,它实现了Map接口,允许我们存储键值对,并且可以根据键直接访问对应的值。 特性 键值对存储:HashMap存储的是键值对数据,可以方便的通过键来获取值。无序:HashMap中…...

10个好用的Mac数据恢复软件推荐—恢复率高达99%
如果您正在寻找最好的 Mac 数据恢复软件来检索意外删除或丢失的文件,那么这里就是您的最佳选择。 我们理解,当您找不到 Mac 计算机或外部驱动器上保存的一些重要文件时,会感到多么沮丧和绝望。这些文件非常珍贵,无论出于何种原因…...

EtherCAT从站EEPROM分类附加信息详解:RXPDO(输入过程数据对象)
0 工具准备 1.EtherCAT从站EEPROM数据(本文使用DE3E-556步进电机驱动器)1 分类附加信息——RXPDO(输入过程数据对象) 1.1 分类附加信息规范 在EEPROM字64开始的区域存储的是分类附加信息,这里存储了包括设备信息、SM配置、FMMU配置在内的诸多信息。每个信息在一段连续的…...
释放锁流程源码剖析
1 释放锁流程概述 ReentrantLock的unlock()方法不区分公平锁还是非公平锁。 首先调用unlock()方法。 unlock()底层使用的是Sync.release(1)方法 public void unlock() {<!-- --> sync.release(1); } release(1)方法会调用tryRelease(1)去尝试解锁。 public fin…...

ComText让机器人有了情节记忆
为了让人类与机器人更好地交流,MIT 计算机科学与人工智能实验室的研究员开发了一个名为 ComText 的程序。这款程序给机器人增加了情节记忆,让它们能够接受更加复杂的命令。目前,他们已经在机器人 Baxter 上测试了程序。 机器人没有情景化的记…...
【Leetcode合集】13. 罗马数字转整数
13. 罗马数字转整数 13. 罗马数字转整数 代码仓库地址: https://github.com/slience-me/Leetcode 个人博客 :https://slienceme.xyz 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符…...
centos oracle11g开启归档模式
要在 CentOS 上停止 Oracle 11g 数据库,你可以按照以下步骤操作: 1.登录到操作系统 首先,使用具有足够权限的用户登录到 CentOS 操作系统。通常情况下,你需要以具有 oracle 用户权限的用户登录。 使用 SYSDBA 权限连接到数据库…...

【数据结构初阶】双链表
双链表 1.双链表的实现1.1结口实现1.2申请结点1.3初始化双链表1.4打印双链表1.5尾插1.6尾删1.7头插1.8头删1.9计算大小1.10查找1.11pos位置插入1.12删除pos位置1.12删除双链表 全部码源 1.双链表的实现 1.1结口实现 #include<stdio.h> #include<stdlib.h> #inclu…...

Django实战:从零到一构建安全高效的Web应用
目录 一、概述 二、版本控制和部署 1、Git版本控制 2、Docker部署 三、数据库配置 1、配置数据库设置 2、创建数据库模型 四、URL路由和视图 1、定义URL路由 2、创建视图 五、模板渲染 1、创建模板 2、在视图中使用模板 总结 一、概述 Django是一个高级Python W…...
Docker build报错总结,版本过新大避雷!
1.速度太慢报错,需要换源; 在DOCKERFILE中添加镜像; RUN echo "deb http://mirror.sjtu.edu.cn/debian bookworm main non-free contrib" > /etc/apt/sources.list, 2.即使在Dockerfile中换源,但在bul…...

spider 网页爬虫中的 AWS 实例数据获取问题及解决方案
前言 AAWS实例数据对于自动化任务、监控、日志记录和资源管理非常重要。开发人员和运维人员可以通过AWS提供的API和控制台访问和管理这些数据,以便更好地管理和维护他们在AWS云上运行的实例。然而,在使用 spider 框架进行网页爬取时,我们常常…...

flink的window和windowAll的区别
背景 在flink的窗口函数运用中,window和windowAll方法总是会引起混淆,特别是结合上GlobalWindow的组合时,更是如此,本文就来梳理下他们的区别和常见用法 window和windowAll的区别 window是KeyStream数据流的方法,其…...

【机器学习】特征工程:特征选择、数据降维、PCA
各位同学好,今天我和大家分享一下python机器学习中的特征选择和数据降维。内容有: (1)过滤选择;(2)数据降维PCA;(3)sklearn实现 那我们开始吧。 一个数据集中…...
短视频账号矩阵系统saas管理私信回复管理系统
一、短视频矩阵号系统源码开发层面如何来解决? 1.短视频矩阵号系统源码搭建中,首先开发者需要保证api接口的稳定性 ,保证权限应用场景满足官方平台的开发预期。api---待发布、用户管理与授权绑定、私信回复与评论管理等是非常重要的权限接口。…...

利用ETLCloud自动化流程实现业务系统数据快速同步至数仓
现代企业有不少都完成了数字化的转型,而还未转型的企业或商铺也有进行数字化转型的趋势,由此可见,数据已经成为企业决策的重要依据。企业需要先获取数据,将业务系统数据同步至数仓进行整合,然后再进行数据分析。为了更…...
学习c#的第十六天
目录 C# 正则表达式 定义正则表达式 字符转义 字符类 定位点 分组构造 Lookaround 概览 数量词 反向引用构造 替换构造 替代 正则表达式选项 其他构造 Regex 类 代码示例 实例 1 实例 2 实例 3 C# 正则表达式 正则表达式 是一种匹配输入文本的模式。.Net 框…...

【论文阅读笔记】Deep learning for time series classification: a review
【论文阅读笔记】Deep learning for time series classification: a review 摘要 在这篇文章中,作者通过对TSC的最新DNN架构进行实证研究,探讨了深度学习算法在TSC中的当前最新性能。文章提供了对DNNs在TSC的统一分类体系下在各种时间序列领域中的最成功…...

如何将vscode和Linux远程链接:
如何将vscode和Linux远程链接: Remote - SSH - 远程登录Linux 安装Remote - SSH 我们下载完后,就会出现这些图标 这里点一下号 查看一下我们的主机名,并复制 输入ssh 用户名主机名 这里是要将ssh这个文件要放在主机下的哪个路径下ÿ…...

快速傅立叶卷积(FFC)
论文 LaMa: Resolution-robust Large Mask Inpainting with Fourier Convolutions https://github.com/advimman/lama 1.Introduce 解决图像绘制问题——缺失部分的真实填充——既需要“理解”自然图像的大尺度结构,又需要进行图像合成。 通常的做法是在一个大型自…...
藏头诗(C语言)
本题要求编写一个解密藏头诗的程序。 注:在 2022 年 7 月 14 日 16 点 50 分以后,该题数据修改为 UTF-8 编码。 输入格式: 输入为一首中文藏头诗,一共四句,每句一行。注意:一个汉字占三个字节。 输出格…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...