当前位置: 首页 > news >正文

JAVA:HashMap在1.8做了哪些优化的详细解析

1、简述

HashMap 是 Java 中最常用的数据结构之一,它以键值对的形式存储数据,允许快速的插入、删除和查找操作。在 JDK 1.8 之前,HashMap 主要是基于数组加链表的结构实现的。然而,在面对大量哈希冲突时(即多个键的哈希值相同时),链表可能会变得非常长,导致查询效率从 O(1) 退化为 O(n)。为了优化这种情况,JDK 1.8 对 HashMap 进行了几个重要的改进,主要包括引入红黑树(Red-Black Tree)和哈希算法的改进。本文将详细讲解这些优化及其背后的设计思路。
在这里插入图片描述

2、JDK 1.8 之前的 HashMap 实现

在 JDK 1.8 之前,HashMap 使用数组和链表的组合结构。当我们插入一个元素时,它首先通过键的哈希值确定数组中的位置(称为桶),如果该位置存在其他元素,新的键值对将被追加到该位置的链表上。

这种结构的优点是简单易实现,且在键分布均匀的情况下性能很好。但在极端情况下,如果大量的键映射到了同一个位置(哈希冲突),链表的长度会增长,查询时间复杂度会从 O(1) 退化到 O(n),这对性能影响较大。

在这里插入图片描述

3、JDK 1.8 对 HashMap 的优化

3.1 引入红黑树(Red-Black Tree)

为了优化链表查询的效率,JDK 1.8 引入了红黑树。当链表的长度超过一定阈值(默认是 8)时,链表会自动转换为红黑树。红黑树是一种自平衡二叉搜索树,查找、插入、删除操作的时间复杂度为 O(log n),因此大幅提升了查询性能。

当链表中的元素少于一定数量(默认是 6)时,红黑树会被转换回链表。这种转换机制在哈希冲突较严重时显著提升了 HashMap 的性能,同时也保证了在数据量较少时的内存开销不会过高。

// HashMap 中的链表转红黑树逻辑示例
if (binCount >= TREEIFY_THRESHOLD) {treeifyBin(tab, hash);
}
  • TREEIFY_THRESHOLD:定义了链表转化为红黑树的阈值,默认值为 8。
  • treeifyBin:负责将链表转化为红黑树。
3.2 动态扩容优化

HashMap 的容量是动态扩展的,当哈希表中的元素数量超过当前容量的 75% 时,会触发扩容操作。在 JDK 1.8 之前,扩容需要重新计算每个键的哈希值并分配到新的位置。JDK 1.8 优化了扩容逻辑,通过更高效的方式重新分配元素。

扩容时,原数组长度翻倍,每个元素要么保持在原位置,要么移动到新的索引位置。通过与新的容量进行简单的按位与运算,JDK 1.8 能快速确定元素在新数组中的位置,从而避免重新计算哈希值,提升了扩容的效率。

// HashMap 扩容时的元素迁移逻辑
int idx = e.hash & (newCapacity - 1);
3.3 改进的哈希算法

在 JDK 1.8 中,HashMap 采用了更好的哈希扰动函数(hash function),目的是减少哈希冲突的发生。通过对哈希值进行一系列位运算,使得高位和低位都能影响最终的数组索引,减少了低质量哈希函数带来的冲突问题。

static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

这一优化主要是通过异或操作,将高位和低位的信息混合在一起,以提高哈希值的随机性,进而降低哈希冲突的概率。

4、优化的性能影响

JDK 1.8 的这些改进显著提升了 HashMap 在大数据量、高冲突场景下的性能:

  • 在链表转换为红黑树后,查找性能从 O(n) 提升为 O(log n),尤其在高冲突情况下,性能提升明显。
  • 动态扩容时避免了重复计算哈希值,扩容效率得到了提升。
  • 改进的哈希算法进一步减少了哈希冲突的概率,提高了哈希表的整体性能。

以下是一个简单的示例代码,展示了 HashMap 在 JDK 1.8 中的工作机制:

import java.util.HashMap;public class HashMapDemo {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();// 插入元素,触发红黑树转换for (int i = 0; i < 20; i++) {map.put("key" + i, i);}// 输出 HashMap 内容map.forEach((key, value) -> System.out.println(key + ": " + value));// 扩容前后检查性能System.out.println("Size before expansion: " + map.size());for (int i = 20; i < 50; i++) {map.put("key" + i, i);}System.out.println("Size after expansion: " + map.size());}
}

5、总结

JDK 1.8 对 HashMap 的优化主要集中在两个方面:提高哈希冲突情况下的查找效率和优化扩容过程。通过引入红黑树结构,HashMap 能够在面对大量哈希冲突时依然保持高效的查询性能;而动态扩容的优化则减少了不必要的哈希值重计算操作。这些优化使得 HashMap 在 JDK 1.8 中性能更加稳定和高效,特别是在大数据量的高并发环境中,表现尤为出色。

这也是为什么在性能敏感的系统中,升级到 JDK 1.8 后 HashMap 的表现更加优越的原因。希望这篇文章能帮助你更好地理解这些优化的实现原理,并在实际开发中加以应用。

相关文章:

JAVA:HashMap在1.8做了哪些优化的详细解析

1、简述 HashMap 是 Java 中最常用的数据结构之一&#xff0c;它以键值对的形式存储数据&#xff0c;允许快速的插入、删除和查找操作。在 JDK 1.8 之前&#xff0c;HashMap 主要是基于数组加链表的结构实现的。然而&#xff0c;在面对大量哈希冲突时&#xff08;即多个键的哈…...

jest使用__mocks__设置模拟函数不生效 解决方案

模拟文件 // __mocks__/axios.js const axios jest.fn(); axios.get jest.fn(); axios.get.mockResolvedValue({data: {undoList: [get data],}, }); export default axios; 测试文件 jest.mock(axios); import Axios from axios;test(mytest, () > {console.log("…...

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…...

笔上云世界微服务版

目录 一、项目背景 二、项目功能 一功能介绍 三、环境准备 • 需要开发的端口 • Mysql 导入数据库 ​编辑 • Redis ​编辑 • RabbitMQ ​编辑 在创建blog虚拟主机(方法如下) • Nacos • Nginx 四、前端部署 五、后端部署 六、测试计划操作 一功能测试 二…...

linux安装redis及Python操作redis

目录 一、Redis安装 1、下载安装包 2、解压文件 3、迁移文件夹 4、编译 5、管理redis文件 6、修改配置文件 7、启动Redis 8、将redis服务交给systemd管理 二、Redis介绍 1、数据结构 ①字符串String ②列表List ③哈希Hash ④集合Set ⑤有序集合Sorted Set 2、…...

node.js内置模块之---stream 模块

stream 模块的作用 在 Node.js 中&#xff0c;stream 模块是一个用于处理流&#xff08;stream&#xff09;的核心模块。流是一种处理数据的抽象方式&#xff0c;允许程序处理大量数据时不会一次性将所有数据加载到内存中&#xff0c;从而提高性能和内存效率。通过流&#xff0…...

《learn_the_architecture_-_aarch64_exception_model》学习笔记

1.当发生异常时&#xff0c;异常级别可以增加或保持不变&#xff0c;永远无法通过异常来转移到较低的权限级别。从异常返回时&#xff0c;异常级别可能会降低或保持不变&#xff0c;永远无法通过从异常返回来移动到更高的权限级别。EL0级不进行异常处理&#xff0c;异常必须在比…...

【C++项目实战】贪吃蛇小游戏

一、引言 贪吃蛇&#xff0c;这款经典的电子游戏&#xff0c;自1976年诞生以来&#xff0c;一直受到全球玩家的喜爱。它的规则简单&#xff0c;玩法直观&#xff0c;但同时也充满了挑战性。在这篇文章中&#xff0c;我们将一起探索如何开发一个贪吃蛇游戏&#xff0c;无论是作为…...

Python基于matplotlib实现树形图的绘制

在Python中&#xff0c;你可以使用matplotlib库来绘制树形图&#xff08;Tree Diagram&#xff09;。虽然matplotlib本身没有专门的树形图绘制函数&#xff0c;但你可以通过组合不同的图形元素&#xff08;如线条和文本&#xff09;来实现这一点。 以下是一个简单的示例&#…...

【UE5 C++课程系列笔记】21——弱指针的简单使用

目录 概念 声明和初始化 转换为共享指针 打破循环引用 弱指针使用警告 概念 在UE C 中&#xff0c;弱指针&#xff08;TWeakPtr &#xff09;也是一种智能指针类型&#xff0c;主要用于解决循环引用问题以及在不需要强引用保证对象始终有效的场景下&#xff0c;提供一种可…...

【游戏设计原理】46 - 魔杖

幻想&#xff0c;人们可以通过多种形式来引发&#xff0c;比如文字&#xff0c;图片&#xff0c;绘画&#xff0c;语言等&#xff0c;但游戏与以上这些形式的区别&#xff0c;正如游戏与其他艺术形式的区别一样&#xff0c;游戏作为一种艺术和娱乐形式&#xff0c;其独特之处在…...

【路径跟踪】PIDMPC

路径跟踪&#xff08;Path Tracking&#xff09;是指在实际行驶过程中&#xff0c;根据预先规划好的路径进行控制&#xff0c;能够沿着设定的路径行驶。常见的路径跟踪算法包括基于模型的控制方法&#xff08;如PID控制器&#xff09;、模型预测控制&#xff08;Model Predicti…...

Spring源码分析之事件机制——观察者模式(二)

目录 获取监听器的入口方法 实际检索监听器的核心方法 监听器类型检查方法 监听器的注册过程 监听器的存储结构 过程总结 Spring源码分析之事件机制——观察者模式&#xff08;一&#xff09;-CSDN博客 Spring源码分析之事件机制——观察者模式&#xff08;二&#xff…...

热备份路由HSRP及配置案例

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;HSRP的相关概念二&#xff0c;…...

仿生的群体智能算法总结之三(十种)

群体智能算法是一类通过模拟自然界中的群体行为来解决复杂优化问题的方法。以下是30种常见的群体智能算法,本文汇总第21-30种。接上文 : 编号 算法名称(英文) 算法名称(中文) 年份 作者 1 Ant Colony Optimization (ACO) 蚁群优化算法 1991 Marco Dorigo 2 Particle Swar…...

CentOS 7系统 OpenSSH和OpenSSL版本升级指南

文章目录 CentOS 7系统 OpenSSH和OpenSSL版本升级指南环境说明当前系统版本当前组件版本 现存安全漏洞升级目标版本升级准备工作OpenSSL升级步骤1. 下载和解压2. 编译安装3. 配置环境 OpenSSH升级步骤1. 下载和解压2. 编译安装3. 创建systemd服务配置4. 更新SSH配置文件5. 设置…...

【专题】2024年出口跨境电商促销趋势白皮书报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38722 在当今全球化加速演进、数字经济蓬勃发展的大背景下&#xff0c;跨境电商行业正以前所未有的态势重塑国际贸易格局&#xff0c;成为各方瞩目的焦点领域。 根据亚马逊发布的《2024年出口跨境电商促销趋势白皮书》&#xff0c;…...

【Ubuntu】不能连上网络

1. ping路由器的IP地址 ping 192.168.1.1 如果ping不通的话&#xff0c;可能是网络故障导致的。需要重启配置ip地址。配置文件 sudo vi /etc/network/interface 2. ping 8.8.8.8 如果ping不通的话&#xff0c;可能是路由器不能链接往外网&#xff1b; 或者路由器显示了当…...

CSS3 框大小

CSS3 框大小 CSS3 是网页设计和开发中不可或缺的一部分,它为开发者提供了更多样化、更灵活的样式和布局选择。在 CSS3 中,框大小(Box Sizing)是一个重要的概念,它决定了元素内容的宽度和高度以及元素整体的大小。本文将详细介绍 CSS3 框大小的概念、用法以及最佳实践。 …...

联发科MTK6771/MT6771安卓核心板规格参数介绍

MT6771&#xff0c;也被称为Helio P60&#xff0c;是联发科技(MediaTek)推出的一款中央处理器(CPU)芯片&#xff0c;可运行 android9.0 操作系统的 4G AI 安卓智能模块。MT6771芯片采用了12纳米工艺制造&#xff0c;拥有八个ARM Cortex-A73和Cortex-A53核心&#xff0c;主频分别…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...