某大厂一面:HashMap 的put方法具体做了哪些操作
HashMap
的 put
方法是一个常用的操作,它将一个键值对插入到哈希表中。下面是 put
方法执行的详细流程,包括各个步骤的解释,并附上相应的代码片段。
1. 检查键是否为 null
如果传入的键为 null
,HashMap
会特别处理这种情况,因为 null
是允许作为键的,但是它会在特殊位置(通常是数组的第一个位置)存储。
if (key == null) {return putForNullKey(value);
}
2. 计算哈希值
对于非 null
的键,HashMap
会首先计算出该键的哈希值。哈希值的计算是通过调用键的 hashCode()
方法,再经过一定的扰动处理,以减少哈希冲突。
int hash = hash(key.hashCode());
int index = indexFor(hash, table.length);
这里的 hash()
是一个方法,用于对键的哈希值进行扰动,indexFor()
方法则用来根据计算出的哈希值找到数组中的位置。
3. 查找位置
接下来,HashMap
会根据计算出的索引(index
)来查找对应的桶(数组位置)。如果该位置已经存在元素,则会检查该位置的链表或红黑树结构,查看是否已经存在相同的键。
for (Entry<K,V> e = table[index]; e != null; e = e.next) {K k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;return oldValue;}
}
4. 插入新元素
如果在相应位置没有找到相同的键,HashMap
会将新的键值对插入到桶中。如果该位置为空,直接插入该元素。如果该位置已经存在链表或红黑树,则会把新元素加入到链表头部或树中。
createEntry(hash, key, value, index);
5. 扩容
HashMap
会根据当前的负载因子(默认是 0.75)来判断是否需要扩容。如果当前元素数量超出了负载因子的限制,HashMap
会进行扩容操作,这会重新计算每个元素的位置,并将元素重新插入到新的数组中。
if (size > threshold)resize();
完整代码示例
public V put(K key, V value) {if (key == null) {return putForNullKey(value);}int hash = hash(key.hashCode());int index = indexFor(hash, table.length);for (Entry<K,V> e = table[index]; e != null; e = e.next) {K k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;return oldValue;}}createEntry(hash, key, value, index);if (size++ >= threshold) {resize();}return null;
}private int hash(int h) {h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
}private int indexFor(int hash, int length) {return hash & (length - 1);
}private void createEntry(int hash, K key, V value, int bucketIndex) {Entry<K,V> e = table[bucketIndex];table[bucketIndex] = new Entry<>(hash, key, value, e);
}private void resize() {// 扩容的具体实现
}
关键点总结:
- 哈希值计算:使用
hashCode
和扰动函数来减少冲突。 - 桶的查找:通过数组索引查找对应位置,如果发生冲突,使用链表或红黑树来存储多个元素。
- 元素插入:如果该位置没有找到相同的键,插入新元素。
- 扩容机制:当负载因子达到一定比例时,
HashMap
会扩展数组并重新散列元素。
这个过程对于每次调用 put
都是会依次执行的,确保 HashMap
的高效插入与查询操作。
相关文章:
某大厂一面:HashMap 的put方法具体做了哪些操作
HashMap 的 put 方法是一个常用的操作,它将一个键值对插入到哈希表中。下面是 put 方法执行的详细流程,包括各个步骤的解释,并附上相应的代码片段。 1. 检查键是否为 null 如果传入的键为 null,HashMap 会特别处理这种情况&…...

WPF基础 | 深入 WPF 事件机制:路由事件与自定义事件处理
WPF基础 | 深入 WPF 事件机制:路由事件与自定义事件处理 一、前言二、WPF 事件基础概念2.1 事件的定义与本质2.2 常见的 WPF 事件类型 三、路由事件3.1 路由事件的概念与原理3.2 路由事件的三个阶段3.3 路由事件的标识与注册3.4 常见的路由事件示例 四、自定义事件处…...

精选100+套HTML可视化大屏模板源码素材
大屏数据可视化以大屏为主要展示载体的数据可视化设计。 “大面积、炫酷动效、丰富色彩”,大屏易在观感上给人留下震撼印象,便于营造某些独特氛围、打造仪式感。 原本看不见的数据可视化后,便能调动人的情绪、引发人的共鸣。 使用方法&…...

如何使用Python爬虫按关键字搜索AliExpress商品:代码示例与实践指南
在电商领域,能够按关键字搜索并获取商品信息对于市场分析、选品和竞品研究至关重要。AliExpress(速卖通)作为全球知名的跨境电商平台,提供了丰富的商品数据。以下将详细介绍如何使用Python爬虫按关键字搜索AliExpress商品…...

No.36 学习 | Python 函数:从基础到实战
最近我在学 Python 编程,今天可算是狠狠钻研了一把 Python 里的函数,感觉脑袋里的知识又充实了不少,赶紧来记一记。 一、Python函数基础概念 (一)pass语句:代码块的“占位符” 在编写代码时,有…...

Unity常用特性(Attribute)用法
一.UnityEngine命名空间 1.[Header(string)] inspector面板上给显示的字段上加一个描述 通常情况下,用于在 Inspector 窗口中创建字段的逻辑分组 public class AttributeTest : MonoBehaviour {[Header("public_field_num")]public int num; }2.[Tool…...

VUE对接deepseekAPI调用
1.先去开放平台注册账号申请api key。开放平台:https://platform.deepseek.com/api_keys 2.你的项目需要有发送请求的axios或者自己写。 npm install axios # 或 yarn add axios 3.创建 API 调用函数 在 Vue 项目中,通常会将 API 调用的逻辑封装到一个…...

【Postman 接口测试】接口测试基础知识
在软件开发与测试领域,接口测试是保障软件质量的关键环节之一,而 Postman 作为一款功能强大且广泛使用的接口测试工具,能帮助我们高效地进行接口测试工作。下面,我们将详细介绍接口测试的基础知识,包括接口的认识、接口…...

谷粒商城——商品服务-三级分类
1.商品服务-三级分类 1.1三级分类介绍 1.2查询三级分类查询-递归树型结构数据获取 1.2.1导入数据pms_catelog.sql到数据表pms_category 1.2.2一次性查出所有分类及子分类 1.2.2.1修改CategoryController.java /*** 查出所有分类以及子分类,以树形结构组装起来*/R…...

视觉语言模型 (VLMs):跨模态智能的探索
文章目录 一. VLMs 的重要性与挑战:连接视觉与语言的桥梁 🌉二. VLMs 的核心训练范式:四种主流策略 🗺️1. 对比训练 (Contrastive Training):拉近正例,推远负例 ⚖️2. 掩码方法 (Masking):重构…...
HarmonyOS NEXT:华为分享-碰一碰开发分享
随着科技的不断进步,智能手机和智能设备之间的互联互通变得越来越重要。华为作为科技行业的领军企业,一直致力于为用户提供更加便捷、高效的使用体验。HarmonyOS NEXT系统的推出,特别是其中的“碰一碰”功能,为用户带来了前所未有…...

宝塔Linux+docker部署nginx出现403 Forbidden
本文主要讲述了宝塔docker部署nginx出现403 Forbidden的原因,以及成功部署前端的方法步骤。 目录 1、问题描述2、问题检测2.1 检测监听端口是否异常2.2 检测Docker容器是否异常2.2.1 打开宝塔Linux的软件商店,找到Docker管理器,查看前端容器是…...
软件测试丨Redis 的数据同步策略以及数据一致性保证
Redis 以其键值存储的方式,为开发者提供了数据快速存取的能力。它不仅支持丰富的数据结构,如字符串、哈希、列表、集合等,而且提供了高效的数据同步与一致性保障机制。正因为如此,Redis 被广泛应用于缓存、消息队列、实时数据分析…...
C语言-运算符
1. 按位与运算符(&) 按位与运算符对两个整数的每一位执行“与”操作。只有当两个相应位都为 1 时,结果才为 1 ;否则为 0。 // 示例 int a 5; // 二进制: 0101 int b 3; // 二进制: 0011 int result a & b; …...

困境如雾路难寻,心若清明步自轻---2024年创作回顾
文章目录 前言博客创作回顾第一次被催更第一次获得证书周榜几篇博客互动最多的最满意的引发思考的 写博契机 碎碎念时也运也部分经验 尾 前言 今年三月份,我已写下一篇《近一年多个人总结》,当时还没开始写博客。四月份写博后,就顺手将那篇总…...

表格标签基本使用
表格主要用于显示、展示数据,因为它可以让数据显示的非常的规整,可读性非常好。特别是后台展示数据的时候,能够熟练运用表格就显得很重要。一个清爽简约的表格能够把繁杂的教据表现得很有条理。 1.<table></table>是用于定义表格…...
【学术会议论文投稿】深度解码:机器学习与深度学习的界限与交融
目录 一、定义与起源:历史长河中的两条轨迹 二、原理差异:从浅层到深层的跨越 三、代码解析:实战中的机器学习与深度学习 机器学习示例:线性回归 深度学习示例:卷积神经网络(CNN) 四、应用差异:各自领…...
使用printmap()函数来打印地图
使用PrintMap()函数可以将地图布局发送到打印机.默认情况下,任务会发送到地图文档保存的默认打印机,但也可以通过自定义一个特定的打印机来执行打印任务 操作方法 1.打开目标地图 2.打开python窗口 3.导入arcpy.mapping模块 import arcpy.mapping as mapping 4.引用活动地…...
MyBatis Plus 的 InnerInterceptor:更轻量级的 SQL 拦截器
在 Spring Boot 项目中使用 MyBatis Plus 时,你可能会遇到 InnerInterceptor 这个概念。 InnerInterceptor 是 MyBatis Plus 提供的一种轻量级 SQL 拦截器,它与传统的 MyBatis 拦截器(Interceptor)有所不同,具有更简单…...

Java复习第四天
一、代码题 1.相同的树 (1)题目 给你两棵二叉树的根节点p和q,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p[1,2,3],q[1,2,3] 输出:true示例 2: 输…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...