Jdk1.7到Jdk1.8 HashMap 发生了什么变化(底层)

从JDK 1.7到JDK 1.8,HashMap在底层实现上发生了显著的变化,

主要体现在数据结构、链表插入方式、哈希算法、扩容机制以及并发性方面。

以下是具体的变化点:

1. 数据结构的变化

  • JDK 1.7:HashMap的底层数据结构是数组+单向链表。当哈希冲突发生时,新的元素会插入到链表的头部(头插法)。
  • JDK 1.8:HashMap的底层数据结构变为数组+链表/红黑树。当链表长度超过一定阈值(默认为8)时,链表会转换成红黑树,以提高查询效率。这种变化使得HashMap在处理大量数据时能够保持较好的性能。

2. 链表插入方式的变化

  • JDK 1.7:链表插入使用的是头插法,即新的元素会被插入到链表的头部。
  • JDK 1.8:链表插入使用的是尾插法。这是因为JDK 1.8在插入元素时需要判断链表长度,尾插法便于统计链表元素个数。同时,尾插法也避免了头插法可能导致的链表反转问题。

3. 哈希算法的变化

  • JDK 1.7:哈希算法相对复杂,涉及多种右移和位运算操作。
  • JDK 1.8:哈希算法进行了简化。这是因为JDK 1.8引入了红黑树,可以在一定程度上弥补简化哈希算法可能带来的散列性降低问题,从而节省CPU资源。

4. 扩容机制的变化

  • JDK 1.7:扩容时,会重新创建一个更大的数组,并将原数组中的元素逐个添加到新数组中。这个过程比较耗费时间和性能。
  • JDK 1.8:扩容机制得到了优化。当达到扩容条件时(容量*负载因子超过阈值),会创建一个大小为原数组两倍的新数组,并采用更高效的方式迁移数据。此外,JDK 1.8还引入了“树化”的概念,即在扩容时,链表长度达到阈值的桶会直接转换为红黑树,以减少扩容操作的时间复杂度。

5. 并发性的改进

  • JDK 1.7:HashMap本身是非线程安全的,在多线程环境下使用时需要额外的同步机制来保证数据一致性。
  • JDK 1.8:虽然HashMap本身仍然是非线程安全的,但JDK 1.8通过一些机制(如synchronized关键字、CAS操作等)提高了其在多线程环境下的性能。然而,对于需要线程安全的场景,仍然建议使用ConcurrentHashMap。

代码讲解

下面是一些简化的源码片段和注释,用于说明JDK 1.7和JDK 1.8中HashMap的关键部分。

JDK 1.7 HashMap 简化源码
// JDK 1.7 HashMap 的简化版本
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {// 省略了大部分成员变量和方法...// 存储元素的数组transient Entry<K, V>[] table;// Entry 是 HashMap 的一个内部类,表示一个键值对static class Entry<K, V> implements Map.Entry<K, V> {final K key;V value;Entry<K, V> next;// 省略了构造方法和其它方法...}// 省略了其它方法...// put 方法(简化版)public V put(K key, V value) {// 对 key 进行哈希运算,定位到数组中的某个位置int hash = hash(key);int i = indexFor(hash, table.length);// 遍历链表,查看是否已存在相同的 keyfor (Entry<K, V> e = table[i]; e != null; e = e.next) {if (e.hash == hash && (e.key.equals(key) || key.equals(e.key))) {V oldValue = e.value;e.value = value;return oldValue;}}// 如果不存在,则添加新的 Entry 到链表中addEntry(hash, key, value, i);return null;}// 添加新的 Entry 到数组中(链表形式)void addEntry(int hash, K key, V value, int bucketIndex) {Entry<K, V> e = table[bucketIndex];table[bucketIndex] = new Entry<>(hash, key, value, e);// 如果数组中的元素数量超过阈值,则进行扩容if (size++ > threshold)resize(2 * table.length);}// 省略了其它方法...
}
JDK 1.8 HashMap 简化源码
// JDK 1.8 HashMap 的简化版本
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>, Cloneable, Serializable {// 省略了大部分成员变量和方法...// 存储元素的数组(在 JDK 1.8 中,这个数组可能存储 Node 或 TreeNode)transient Node<K, V>[] table;// Node 是 JDK 1.8 中新引入的一个内部类,用于替代 Entrystatic class Node<K, V> implements Map.Entry<K, V> {final int hash;final K key;V value;Node<K, V> next;// 省略了构造方法和其它方法...}// 当链表长度超过8时,会转换为红黑树,TreeNode 是红黑树的一个节点static final class TreeNode<K, V> extends LinkedHashMap.Entry<K, V> {TreeNode<K, V> parent;TreeNode<K, V> left;TreeNode<K, V> right;TreeNode<K, V> prev;// 省略了红黑树相关的其它方法和成员变量...}// 省略了其它方法...// put 方法(简化版)public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}// 实际的 put 逻辑(简化版)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;// 定位到数组中的某个位置,如果为空则直接插入新的 Nodeif ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {// 如果不为空,则可能是链表或红黑树Node<K, V> e;K k;// 省略了部分逻辑,包括树化处理和链表遍历...// 如果找到了相同的 key,则更新 value 并返回旧值if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {V oldValue = e.value;e.value = value;return oldValue;}// 如果没找到相同的 key,则将新的 Node 插入到链表的末尾(或树中)// 省略了具体的插入逻辑...}// 省略了其它逻辑,包括扩容和计数更新...return null;}// 省略了其它方法...
}

注释说明

  • 在JDK 1.7中,HashMap使用Entry内部类来表示键值对,而在JDK 1.8中,引入了Node内部类来替代Entry
  • JDK 1.8中新增了TreeNode内部类,用于在链表长度超过8时将链表转换为红黑树,以提高性能。
  • JDK 1.8中的put方法逻辑更加复杂,因为它需要处理链表和红黑树两种情况。
  • 扩容机制在JDK 1.8中也有所改进,使得扩容过程更加平滑。

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

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

相关文章

RJ45 网线线序、E1线线序、2B+d线序

1、RJ45 网线线序 线序排列如下&#xff1a; T568A线序&#xff1a;绿白—1&#xff0c;绿—2&#xff0c;橙白—3&#xff0c;蓝—4&#xff0c;蓝白—5&#xff0c; 橙—6&#xff0c;棕白—7&#xff0c;棕—8 T568B线序&#xff1a;橙白—1&#xff0c;橙—2&#xff0c…

FreeBSD安装教程

FreeBSD 是一个功能强大且可靠的开源 UNIX 操作系统&#xff0c;适合服务器和桌面环境。本文将介绍如何安装 FreeBSD&#xff0c;从系统准备到基础设置&#xff0c;为你快速上手提供帮助。 一、准备工作 1. 硬件要求 CPU&#xff1a;支持 x86 或 AMD64 架构的处理器。 内存&a…

Fortify_SCA_v24.2.0

前言 Fortify SCA 支持丰富的开发环境、语言、平台和框架&#xff0c;可对开发与生产混合环境进行安全检查。25 种编程语言 超过 911,000 个组件级 API 可检测超过 961 个漏洞类别 支持所有主流平台、构建环境和 IDE。 Fortify SCA是一款商业软件&#xff0c;价格较为昂贵&am…

MyBatis框架的入门

目录 MyBatis第一章&#xff1a;框架的概述1. MyBatis框架的概述 第二章&#xff1a;MyBatis的入门程序1. 创建数据库和表结构2. MyBatis的入门步骤 MyBatis 第一章&#xff1a;框架的概述 1. MyBatis框架的概述 MyBatis是一个优秀的基于Java的持久层框架&#xff0c;内部对…

rust的axux框架开启负载均衡和重启自身的方法-会议签到的调优

开启负载均衡和重启自身 更换axum后台的意外解决的尝试在caddy反代,使用负载均衡,加多一个节点axum主程序 ip映射信息做全局共享axum重启自身刷新全局共享配置 前期刚实现了rust的后台关键业务.结果出现了两类大问题停止服务.在正用着的时候,出现很多意外,真是刺激… 更换axum…

深入理解数据库索引:原理、分类与优化

目录 1. 索引基础1.1 索引的工作原理 2. 最左匹配原则2.1 什么是最左匹配原则&#xff1f;2.2 示例说明2.3 最左匹配原则的图示 3. 索引分类3.1 按数据结构分类3.2 按索引列数分类3.3 按唯一性分类3.4 按存储方式分类 4. 聚集索引与非聚集索引的区别4.1 聚集索引4.2 非聚集索引…

Three.js相机Camera控件知识梳理

原文&#xff1a;https://juejin.cn/post/7231089453695238204?searchId20241217193043D32C9115C2057FE3AD64 1. 相机类型 Three.js 主要提供了两种类型的相机&#xff1a;正交相机&#xff08;OrthographicCamera&#xff09;和透视相机&#xff08;PerspectiveCamera&…

Bernstein-type inequality (BTI)

参见论文&#xff1a; Dual-Functional Artificial Noise (DFAN) Aided Robust Covert Communications in Integrated Sensing and Communications 理论 \boxed{} ​用于加框 Lemma 2. (BTI): For any A ∈ C N N \mathbf{A} \in\mathbb{C}^{N\times N} A∈CNN, b ∈ C N …

一条线上的点

给你一个数组 points &#xff0c;其中 points[i] [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。 提示&#xff1a; 1 < points.length < 300points[i].length 2-104 < xi, yi < 104points 中的所有点 互不相同 解析&#xff1a;使用斜…

XX服务器上的npm不知道咋突然坏了

收到同事的V&#xff0c;说是&#xff1a;182上的npm不知道咋突然坏了&#xff0c;查到这里了&#xff0c;不敢动了。 咱一定要抓重点&#xff1a;突然坏了。这里的突然肯定不是瞬间&#xff08;大概率是上次可用&#xff0c;这次不可用&#xff0c;中间间隔了多长时间&#x…

GNSS定位局限性与综合PNT及5G定位技术研究

摘要 本文主要介绍了GNSS定位技术的系统组成与原理、发展历程、应用领域及现状&#xff0c;并分析了其存在的局限性&#xff0c;如信号遮挡、多路径效应、大气层干扰等。文章还探讨了综合PNT技术的体系架构、多源信息融合方法以及智能化算法在PNT中的应用&#xff0c;强调了综…

/hbase/oldWALs 文件

/hbase/oldWALs 是 HBase 中的一个目录&#xff0c;用于存储那些不再需要用于恢复目的的 WAL&#xff08;Write-Ahead Log&#xff09;文件。这些文件在 HBase 确认所有的数据都已经从 MemStore 持久化到 HFile 之后&#xff0c;会被移动到这个目录。 /hbase/oldWALs 目录中的…

HALCON 算子 之 形态学操作算子

文章目录 什么是形态学操作&#xff1f;为什么要形态学操作&#xff1f;怎么形态学操作&#xff1f;腐蚀 —— Erosionerosion1erosion_circle&#xff1a;erosion_rectangle1&#xff1a; 膨胀 —— Dilationdilation1dilation_circledilation_rectangle1 打开 —— Openingop…

[金盾杯 2024] PWN 复现

好长时间不作题了&#xff0c;在复现平台上看到这个比赛&#xff0c;作了一下&#xff0c;题过于简单了。不过密码一言难尽。 Orange 要说libc-2.23有多老&#xff0c;我一开始学PWN的时候还有不少&#xff0c;这两年几乎不见了。一些比赛估计是拿的旧题。 远看像个堆题&…

pytest入门九:feature

fixture是pytest特有的功能&#xff0c;用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识&#xff0c;定义在函数前面。在你编写测试函数的时候&#xff0c;你可以将此函数名称做为传入参数&#xff0c;pytest将会以依赖注入方式&#xff0c;将该函数…

uniapp Vue3 语法实现浏览器中音频录制、停止、保存、播放、转码、实时音频输出

一、引言 在现代 Web 应用开发中,音频处理功能变得越来越重要。本文将详细介绍如何使用 uniapp 结合 Vue3 语法在浏览器环境中实现音频录制、停止、保存、播放、转码以及实时音频输出等一系列功能。通过深入剖析代码结构和功能实现细节,帮助读者全面理解和掌握相关技术,以便…

【jpa】会什么jpa会自动新建一个hibernate_sequence表

目录 1. 说明2. 主键生成策略3. hibernate_sequence表的创建4. 如何避免自动创建hibernate_sequence表 1. 说明 1.JPA&#xff08;Java Persistence API&#xff09;在默认情况下&#xff0c;如果使用Hibernate作为持久化框架&#xff0c;并且没有显式指定主键生成策略&#x…

秒优科技-供应链管理系统 login/doAction SQL注入漏洞复现

0x01 产品简介 秒优科技提供的供应链管理系统,即秒优SCM服装供应链管理系统,是一款专为服装电商企业设计的全方位解决方案。是集款式研发、订单管理、物料管理、生产管理、工艺管理、收发货管理、账单管理、报表管理于一体的服装电商供应链管理解决方案。它涵盖了从企划到开…

【TF-IDF】Hugging Face Model Recommendation System

利用了机器学习技术的模型检索 TF-IDF (Term Frequency-Inverse Document Frequency) 文本特征提取例子This project is a Hugging Face Model Recommendation System designed to assist users in discovering the most suitable models based on their task descriptions. Th…

136.WEB渗透测试-信息收集-小程序、app(7)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;135.WEB渗透测试-信息收集-小程序、app&#xff08;6&#xff09; 进入之后我们通过输入…