JDK17 HashMap
HashMap
ArrayList用动态数组存放元素,而HashMap用动态数组(桶)存储键值对。
如果两个键值对映射到桶同一个索引,则称为散列冲突。HashMap采用拉链法解决冲突,即桶中每个索引指向一个链表或者红黑树,多个键值对存放在同一个链表/红黑树中。
拉链法的优点是:
- 链表是动态申请的,适合动态扩容的桶。
- 解决冲突方法比较简单,无堆积现象(非键冲突键值对不会冲突)。查找效率高。
- 键值对规模较大时可以充分利用桶索引,节省空间。
拉链法的缺点是:键值对规模较小时,浪费空间。而ThreadLocalMap用的就是开放地址法解决冲突。
构造器方法
HashMap的构造器方法有很多,最常见的有2个,一个设置初始容量,一个不设置初始容量。
| 方法 | 含义 |
|---|---|
HashMap(int initialCapacity) | 指定初始容量 |
public HashMap() | 默认初始容量为16 |
推荐指定初始容量,原因是如果默认初始容量不足以存储元素,HashMap会扩容。每次扩容都会将元素重新计算哈希值并放入新桶,非常消耗性能。
因此初始容量设为expectedSize / 0.75F + 1.0F。
public HashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);if (initialCapacity > MAXIMUM_CAPACITY) // MAXIMUM_CAPACITY = 1 << 30.也就是2的30次方。initialCapacity = MAXIMUM_CAPACITY; if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " +loadFactor);this.loadFactor = loadFactor;// tableSizeFor方法是取比initialCapacity大的最小的2的次幂// threshold=capacity * load factor,数组容量超过threshold则扩容this.threshold = tableSizeFor(initialCapacity);
}
键值对
HashMap采用Node静态内部类存储元素。散列值是为了快速定位桶索引。next表示链表下一个Node节点。

如果链表达到一定规模,将链表转为红黑树存储元素。
哈希映射
HashMap<K, V>的键可以是任意类型,为了将键对象映射为桶索引,第一步调用hash(Object key)方法将键对象散列为int类型散列值h。
static final int hash(Object key) {int h;// 如果key == null, 则数组下标为0// 如果key != null, 调用key的hashCode()方法计算哈希值h// h >>> 16 是获取h的高16位// h ^ (h >>> 16)是将低16位与高16位进行异或运算return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
第二步,数组下标i = (n - 1) & hash,其中n是桶容量,且为2的次幂。第三步,HashMap将键值对存储在桶的索引i位置。
散列值h是int类型,范围很大。但是通常情况下,内存中数组容量不会太大,通常用不着h的高位。这会导致更频繁的冲突,即众多元素散列到同一个索引,导致部分索元素众多,部分索引元素过少,不平衡。为了解决这个问题,HashMap将低16位与高16位进行异或运算,意图减少冲突。
为了提高计算效率,HashMap规定桶的容量是2的次幂,使得(n - 1) & hash = hash % n,与运算比取模运算效率更高。当n是2的m次方,则n-1的低位是m个1,(n - 1)&hash就是将hash的低m位设为索引。
桶扩容
如果键值对越来越多,而桶不扩容,则单个索引的链表/红黑树会存放过多元素,影响查询效率。为了降低冲突,提高查询效率,因此桶扩容。
扩容时机是元素数量达到容量*加载因子,源码为size > threshold。默认加载因子是0.75,即数组中超过75%的索引不为空,为红黑树/链表,则扩容。
桶扩容源码在resize()方法。resize()方法第一部分是根据旧容量oldCap和旧阈值oldThr计算新容量newCap和新阈值newThr。主要有以下几种情况:
- 调用无参构造器后初次调用
resize()方法,oldCap=0, oldThr = 0.则newCap = 16, newThr = 12。 - 调用有参构造器
HashMap(int initialCapacity)后初次调用resize()方法,oldCap = 0,oldThr不为0且为2的次幂,则newCap=oldThr, newThr=newCap*loadFactor。 - 桶容量
oldCap>=2^30,则threadhold设为最大值,表示不再扩容。 oldCap >= 16, oldCap * 2 < 2^30,则newThr = oldThr * 2。即将阈值加倍。

得到阈值之后执行扩容。桶索引元素非空有3种情况:1. 红黑树。2. 链表。 3. 单个键值对。如果是单个键值对,则重新映射到新索引。

如果是链表,将其拆分为低位链表和高位链表,分别放在新桶的原索引和原索引+oldCap。
假设oldCap=16, newCap=32,则扩容前hash=3,hash=19, hash=35的元素都存在j=3的链表上。扩容后hash=3,hash=35仍然在j=3,而hash=19会移动到j=19。HashMap试图将原链表的键值对均分到新链表的j及j + oldCap索引。
HashMap采用拉链法存储键值对。

时间复杂度
相关文章:
JDK17 HashMap
HashMap ArrayList用动态数组存放元素,而HashMap用动态数组(桶)存储键值对。 如果两个键值对映射到桶同一个索引,则称为散列冲突。HashMap采用拉链法解决冲突,即桶中每个索引指向一个链表或者红黑树,多个键…...
算法随笔_23: 通过删除字母匹配到字典里最长单词
上一篇:算法随笔_22:数组中的k-diff对-CSDN博客 题目描述如下: 给你一个字符串 s 和一个字符串数组 dictionary ,找出并返回 dictionary 中最长的字符串,该字符串可以通过删除 s 中的某些字符得到。 如果答案不止一个,返回长度最长且字母序…...
ansible自动化运维实战--通过role远程部署nginx并配置(8)
文章目录 1、准备工作2、创建角色结构3、编写任务4、准备配置文件(金甲模板)5、编写变量6、编写处理程序7、编写剧本8、执行剧本Playbook9、验证-游览器访问每台主机的nginx页面 在 Ansible 中,使用角色(Role)来远程部…...
Python网络自动化运维---用户交互模块
文章目录 目录 文章目录 前言 实验环境准备 一.input函数 代码分段解析 二.getpass模块 前言 在前面的SSH模块章节中,我们都是将提供SSH服务的设备的账户/密码直接写入到python代码中,这样很容易导致账户/密码泄露,而使用Python中的用户交…...
计算机的错误计算(二百二十二)
摘要 利用大模型化简计算 实验表明,虽然结果正确,但是,大模型既绕了弯路,又有数值计算错误。 与前面相同,再利用同一个算式看看另外一个大模型的化简与计算能力。 例1. 化简计算摘要中算式。 下面是与一个大模型的…...
音频 PCM 格式 - raw data
文章目录 raw 音频格式:PCM其他音频格式:mp31. 无损压缩音频(类比 PNG 图像)2. 有损压缩音频(类比 JPEG 图像) 试了一下科大讯飞的音频识别云 api,踩了点坑 与本文无关:讯飞的 api 使…...
mybatis(78/134)
前天学了很多,关于java的反射机制,其实跳过了new对象,然后底层生成了字节码,创建了对应的编码。手搓了一遍源码,还是比较复杂的。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE …...
连接 OpenAI 模型:基础操作
在这一部分中,我们将介绍如何连接 OpenAI 模型,设置 API 密钥,并使用 Spring AI 的 ChatClient 与 OpenAI 模型进行简单的对话。Spring AI 为集成 OpenAI 模型提供了方便的工具,使得开发者能够更轻松地与 GPT 系列模型进行交互。 …...
数据分箱 baggingboosting onehot独热编码 woe编码 sklearn的ensemble(集成学习)
目录 数据分箱就是将连续变量离散化。 bagging&boosting onehot独热编码 独热编码的结果如下: woe编码 WOE编码的基本原理 步骤一:计算WOE 步骤二:应用WOE WOE编码的优点 示例 数据示例 步骤一:计算每个类别的违约…...
企业微信开发010_使用WxJava企业微信开发框架_封装第三方应用企业微信开发003_并且实现多企业授权访问---企业微信开发012
继续来看吧,上一节,已经把config部分,代码都拿过来了: 并且把企业微信第三方应用开发部分,对应的config的配置,mutiltp 代码拿过来了,并且把yml中的配置也给出了. 然后,这里说一下config中的内容,到时候自己看也可以看懂 其实就是封装了,当系统启动,加载企微模块,这个时候,会…...
Office2021下载与安装保姆级教程【Office Tool Plus】
Office Tool Plus安装Office2021 下载Office Tool Plus安装OfficeⅠ. 清除旧版本Ⅱ. 配置安装参数Ⅲ. 安装许可证Ⅳ. 激发(JH)Office 本文介绍使用Office Tool Plus工具下载、安装、部署Office 2021全过程。 下载Office Tool Plus OfficeToolPlus是一个…...
salesforce公式字段 ISBLANK 函数和 <> NULL的区别
在 Salesforce 公式字段中,ISBLANK 函数和 <> NULL 的作用都可以用来检查字段是否有值,但它们的行为有一些显著的区别。以下是它们的详细对比和适用场景: 1. 基本区别 功能ISBLANK<> NULL主要作用检查字段是否为空(适…...
Unity在WebGL中拍照和录视频
原工程地址https://github.com/eangulee/UnityWebGLRecoder Unity版本2018.3.6f1,有点年久失修了 https://github.com/xue-fei/Unity.WebGLRecorder 修改jslib适配了Unity2021 效果图 录制的视频 Unity在WebGL中拍照和录视频...
AIGC时代下的Vue组件开发深度探索
文章目录 一、AIGC时代对Vue组件开发的深远影响二、Vue组件开发基础与最佳实践三、AIGC技术在Vue组件开发中的具体应用四、结论与展望 随着人工智能技术的飞速发展,AIGC(人工智能生成内容)时代已经悄然来临。在这个时代背景下,软件…...
【外文原版书阅读】《机器学习前置知识》1.线性代数的重要性,初识向量以及向量加法
目录 编辑 编辑 1.Chapter 2 Why Linear Algebra? 2.Chapter 3 What Is a Vector? 个人主页:Icomi 大家好,我是Icomi,本专栏是我阅读外文原版书《Before Machine Learning》对于文章中我认为能够增进线性代数与机器学习之间的理解的…...
Kafka运维宝典 (三)- Kafka 最大连接数超出限制问题、连接超时问题、消费者消费时间超过限制问题详细介绍
Kafka运维宝典 (三) 文章目录 Kafka运维宝典 (三)一、Kafka Broker 配置中的最大连接数超出限制问题1. 错误原因2. 相关 Kafka 配置参数2.1 connections.max2.2 max.connections.per.ip2.3 num.network.threads2.4 connections.ma…...
SpringBoot开发(二)Spring Boot项目构建、Bootstrap基础知识
1. Spring Boot项目构建 1.1. 简介 基于官方网站https://start.spring.io进行项目的创建. 1.1.1. 简介 Spring Boot是基于Spring4框架开发的全新框架,设计目的是简化搭建及开发过程,并不是对Spring功能上的增强,而是提供了一种快速使用Spr…...
【FISCO BCOS】二十四、通过Java SDK对FISCO BCOS进行压力测试
Java SDK Demo是基于Java SDK的基准测试集合,能够对FISCO BCOS节点进行压力测试。Java SDK Demo提供有合约编译功能,能够将Solidity合约文件转换成Java合约文件,此外还提供了针对转账合约、CRUD合约以及AMOP功能的压力测试示例程序。本篇我们来讲讲使用java SDK压力测试的操…...
【PyTorch】4.张量拼接操作
个人主页:Icomi 在深度学习蓬勃发展的当下,PyTorch 是不可或缺的工具。它作为强大的深度学习框架,为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术,能够处理复杂的数据模式。通过 PyTorch࿰…...
新电脑安装系统找不到硬盘原因和解决方法来了
有不少网友反馈新电脑采用官方u盘方式装win10或win100出现找不到硬盘是怎么回事?后来研究半天发现是bios中开启了rst(vmd)模式。如果关闭rst模式肯定是可以安装的,但这会影响硬盘性能,有没有办法解决开启rst模式的情况安装win10或win11呢&…...
Python3 【高阶函数】水平考试:30道精选试题和答案
Python3 【高阶函数】水平考试:30道精选试题和答案 试卷说明 本试卷包含:选择题:15 道、填空题:10 道和 编程题:5 道,总分 100 分。每道题后附有答案和解析。 高阶函数测试试卷 满分:100 分 …...
「 机器人 」仿生扑翼飞行器中的“被动旋转机制”概述
前言 在仿生扑翼飞行器的机翼设计中,模仿昆虫翼的被动旋转机制是一项关键技术。其核心思想在于:机翼旋转角度(攻角)并非完全通过主动伺服来控制,而是利用空气动力和惯性力的作用,自然地实现被动调节。以下对这种设计的背景、原理与优势进行详细说明。 1. 背景:昆虫的被动…...
Android GLSurfaceView 覆盖其它控件问题 (RK平台)
平台 涉及主控: RK3566 Android: 11/13 问题 在使用GLSurfaceView播放视频的过程中, 增加了一个播放控制面板, 覆盖在视频上方. 默认隐藏setVisibility(View.INVISIBLE);点击屏幕再显示出来. 然而, 在RK3566上这个简单的功能却无法正常工作. 通过缩小视频窗口可以看到, 实际…...
【C++】类和对象(五)
1、初始化列表 作用:C提供了初始化列表语法,用来初始化属性。 语法: 构造函数():属性1(值1),属性2(值2)...{}示例: #include<i…...
在win11下搭建ios开发环境
就是安装VMware,然后安装mac虚拟机。 主要参考了这一篇:windows上安装macOS系统虚拟机_windows安装macos虚拟机-CSDN博客 还参考了这一篇:【保姆级别教程】VMware虚拟机安装Mac OS15苹果系统附带【VMware TooLS安装】【解锁虚拟机】和【Mac…...
Maven的下载安装配置
maven的下载安装配置 maven是什么 Maven 是一个用于 Java 平台的 自动化构建工具,由 Apache 组织提供。它不仅可以用作包管理,还支持项目的开发、打包、测试及部署等一系列行为 Maven的核心功能 项目构建生命周期管理:Maven定义了项目构建…...
Mysql主从复制+MHA实验笔记[特殊字符]
目录 基本概念 工作原理 优势 环境准备:四台centos-其中三台mysql,一台MHA 配置一主两从 安装MHA 配置无密码认证 配置MHA 模拟master故障 基本概念 MySQL 主从复制:是 MySQL 数据库中实现数据冗余、数据备份和高可用性的重要技术手…...
vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
1. 基础用法 在 Vue3 中,v-model 在组件上的使用有了更灵活的方式。默认情况下,v-model 使用 modelValue 作为 prop,update:modelValue 作为事件。 1.1 基本示例 <!-- CustomInput.vue --> <template><input:value"mo…...
面向长文本的多模型协作摘要架构:多LLM文本摘要方法
多LLM摘要框架在每轮对话中包含两个基本步骤:生成和评估。这些步骤在多LLM分散式摘要和集中式摘要中有所不同。在两种策略中,k个不同的LLM都会生成多样化的文本摘要。然而在评估阶段,多LLM集中式摘要方法使用单个LLM来评估摘要并选择最佳摘要,而分散式多LLM摘要则使用k个LLM进行…...
Python中容器类型的数据(上)
若我们想将多个数据打包并且统一管理,应该怎么办? Python内置的数据类型如序列(列表、元组等)、集合和字典等可以容纳多项数据,我们称它们为容器类型的数据。 序列 序列 (sequence) 是一种可迭代的、元素有序的容器类型的数据。 序列包括列表 (list)…...
