Java中对HashMap的深度分析

《JavaCollections》 很详细的java collection 讲解,希望能够帮助大家.。。。。。 立即下载

 HashMap可谓JDK的一大实用工具,把各个Object映射起来,实现了“键--值”对应的快速存取。但实际里面做了些什么呢

在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java 虚拟机规范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到很好的答案,于是一气之下把JDK的src 解压出来研究,扩然开朗,遂写此文,跟大家分享感受和顺便验证我理解还有没有漏洞。 这里就拿HashMap来研究吧。

HashMap可谓JDK的一大实用工具,把各个Object映射起来,实现了“键--值”对应的快速存取。但实际里面做了些什么呢?

在这之前,先介绍一下负载因子和容量的属性。大家都知道其实一个 HashMap 的实际容量就 因子*容量,其默认值是 16×0.75=12; 这个很重要,对效率很一定影响!当存入HashMap的对象超过这个容量时,HashMap 就会重新构造存取表。这就是一个大问题,我后面慢慢介绍,反正,如果你已经知道你大概要存放多少个对象,最好设为该实际容量的能接受的数字。

两个关键的方法,put和get:

先有这样一个概念,HashMap是声明了 Map,Cloneable, Serializable 接口,和继承了 AbstractMap 类,里面的 Iterator 其实主要都是其内部类HashIterator 和其他几个 iterator 类实现,当然还有一个很重要的继承了Map.Entry 的 Entry 内部类,由于大家都有源代码,大家有兴趣可以看看这部分,我主要想说明的是 Entry 内部类。它包含了hash,value,key 和next 这四个属性,很重要。put的源码如下

public Object put(Object key, Object value) { 
Object k = maskNull(key); 

这个就是判断键值是否为空,并不很深奥,其实如果为空,它会返回一个static Object 作为键值,这就是为什么HashMap允许空键值的原因。

int hash = hash(k); 
int i = indexFor(hash, table.length); 

这连续的两步就是 HashMap 最牛的地方!研究完我都汗颜了,其中 hash 就是通过 key 这个Object的 hashcode 进行 hash,然后通过 indexFor 获得在Object table的索引值。

table?不要惊讶,其实HashMap也神不到哪里去,它就是用 table 来放的。最牛的就是用 hash 能正确的返回索引。其中的hash算法,我跟JDK的作者 Doug 联系过,他建议我看看《The art of programing vol3》可恨的是,我之前就一直在找,我都找不到,他这样一提,我就更加急了,可惜口袋空空啊!

不知道大家有没有留意 put 其实是一个有返回的方法,它会把相同键值的 put 覆盖掉并返回旧的值!如下方法彻底说明了 HashMap 的结构,其实就是一个表加上在相应位置的Entry的链表:

for (Entry e = table[i]; e != null; e = e.next) { 
if (e.hash == hash && eq(k, e.key)) { 
Object oldvalue = e.value; 
e.value = value; //把新的值赋予给对应键值。 
e.recordAccess(this); //空方法,留待实现 
return oldvalue; //返回相同键值的对应的旧的值。 
} 
} 
modCount++; //结构性更改的次数 
addEntry(hash, k, value, i); //添加新元素,关键所在! 
return null; //没有相同的键值返回 
} 
我们把关键的方法拿出来分析:
void addEntry(int hash, Object key, Object value, int bucketIndex) { 
table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]); 
因为 hash 的算法有可能令不同的键值有相同的hash码并有相同的table索引,如:key=“33”和key=Object g的hash都是-8901334,那它经过indexfor之后的索引一定都为i,这样在new的时候这个Entry的next就会指向这个原本的table[i],再有下一个也如此,形成一个链表,和put的循环对定e.next获得旧的值。到这里,HashMap的结构,大家也十分明白了吧?
if (size++ >= threshold) //这个threshold就是能实际容纳的量 
resize(2 * table.length); //超出这个容量就会将Object table重构 

所谓的重构也不神,就是建一个两倍大的table(我在别的论坛上看到有人说是两倍加1,把我骗了),然后再一个个indexfor进去!注意!!这就是效率!!如果你能让你的HashMap不需要重构那么多次,效率会大大提高!

说到这里也差不多了,get比put简单得多,大家,了解put,get也差不了多少了。对于collections我是认为,它是适合广泛的,当不完全适合特有的,如果大家的程序需要特殊的用途,自己写吧,其实很简单。(作者是这样跟我说的,他还建议我用LinkedHashMap,我看了源码以后发现,LinkHashMap其实就是继承HashMap的,然后override相应的方法,有兴趣的同人,自己looklook)建个 Object table,写相应的算法,就ok啦。

举个例子吧,像 Vector,list 啊什么的其实都很简单,最多就多了的同步的声明,其实如果要实现像Vector那种,插入,删除不多的,可以用一个Object table来实现,按索引存取,添加等。

如果插入,删除比较多的,可以建两个Object table,然后每个元素用含有next结构的,一个table存,如果要插入到i,但是i已经有元素,用next连起来,然后size++,并在另一个table记录其位置。

DC综合中set_dft_signal的实战配置与优化策略 本文深入解析了DC综合中set_dft_signal命令的实战配置与优化策略。文章从命令的核心作用出发,详细拆解了-view、-type、-usage等关键参数,并通过扫描使能与时钟门控的实战案例,展示了如何正确配置以实现测试模式下的功耗优化。同时,文章总结了高级优化策略、与低功耗流程的协同方法以及常见错误排查清单,旨在帮助数字芯片设计工程师构建高可测性、低功耗的稳健DFT基础。 阅读详情

相关推荐

从零开始安装 Windows 11 和 Ubuntu 22.04 双系统

本文详解Windows与Ubuntu 22.04双系统安装流程:需提前确认BIOS模式(UEFI/GPT或Legacy/MBR),关闭BitLocker加密、设备加密及快速启动;推荐Rufus/Ventoy制作启动盘。安装时需规划分区方案(建议单独划分EFI系统分区),注意引导器安装位置选择。双系统启动通过BIOS引导顺序管理,安装后需同步Windows与Linux系统时间。教程适配主流UEFI+GPT设备,强调操作前数据备份及Windows更新策略调整,避免兼容性问题。

萑澈的博客 3765

java Collections类 详解

java 集合篇章——Collections类常用方法讲解及演示。

优快云 / 稀土掘金/ B站 / GitHub: Cyan_RA9 7133

经纬度转换为UTM坐标

UTM(通用横向墨卡托投影): 是一种以米为单位的坐标系统,用于地图和GPS导航。将地球划分为60个纵向的区域。每个区域宽6度,从赤道开始往南北两级方向划分。每个区域都有一个特定的字母。

weixin_45626706的博客 7275

Java的Collections类

只对sort方法举例,其他方法类似。 1.sort()方法:对集合进行排序(主要使用的方法) 第一种:Comparable 排序接口 若一个类实现了Comparable接口,就意味着“该类支持排序”。 假设“有一个List列表(或数组),里面的元素是实现了Comparable接口的类”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。 此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(Tr

a1013552415的博客 680

TLV320AIC3204音频CODEC硬件设计与调试实战

本文深入解析了TLV320AIC3204音频CODEC的硬件设计与调试实战。文章从芯片功能定位入手,详细阐述了电源时钟设计、模拟输入电路等关键硬件设计要点,并提供了软件驱动配置与分层调试方法,帮助工程师有效规避常见陷阱,解决底噪、失真等典型音频调试问题。

zero1的博客 1122

操作系统笔记(含王道计算机考研——操作系统课件)

操作系统(OS) 笔记根据B站王道计算机考研——操作系统视频整理所得,视频链接:https://b23.tv/0I2qex 视频中所用课件:链接:https://pan.baidu.com/s/101bFWm0Tv0emNpEneidYPA 提取码:y3dd 1.计算机系统概述 1.简介 什么是操作系统? 操作系统(Operating Ststem, OS)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配,以提供给用户和其他软件方便的接口和环境,它是

拧发条鸟的博客 6万+

【Java 基础篇】Java Collection详解

Collection是Java集合框架的根接口,它定义了一些基本的操作和行为,如添加、删除、遍历等。List和Set。List是一个有序的集合,可以包含重复元素。它提供了按索引访问、插入、删除等操作。常见的实现类有ArrayListLinkedList和Vector。Set是一个不允许包含重复元素的集合。它提供了高效的元素查找和去重。常见的实现类有HashSetTreeSet和。此外,Map接口也是Collection框架的一部分,它提供了键值对的存储和操作。Map中的键是唯一的,值可以重复。

繁依Fanyi的博客 7278

嵌入式工程师成长之路(7)——算法学习

算法大全1、风仲达——算法笔记2、坐在马桶上学算法3、啊哈算法4、深度强化学习实验室。

云轩阁 4万+

java Collections基本概念和常用方法

Collections.shuffle 就是随机排序 你执行一次他就随机一次 每一次都是不一样的 怎么排序主要看运气。Collections的方法都是针对list集合的 所以 我们先引入List的依赖。Collections是一个类 他在java的util包下 所以使用它是需要导包的。Collections是一个静态方法的集合类 他里面的方法都是静态的。和我们的添加顺序正好反过来了 就是让现在的顺序整个反过来。可以看到 这就成了一个升序排序的集合了。

weixin_45966674的博客 809

从零到一构建一个智能爬虫 Agent 完整教程

本文将打造一个具备自主决策、动态解析、反反爬、持久化能力的智能爬虫 Agent

数据知道的博客 4792

九天揽月带你玩转Ardupilot 的EKF2纸老虎(1)

目录 目录 摘要 1.kalman基础知识储备 摘要 本文主要记录自己学习ardupilot的ekf2代码的过程,相信很多人想移植或者学习ekf2,看到眼花缭乱的代码无从下手。九天揽月将带你玩转Ardupilot 的EKF2纸老虎 1.kalman基础知识储备 (1)先来看下最基础也是最重要的线性kalman 总结:不要害怕kalman,只要你可以懂得线性kal...

陌城烟雨 1万+

Java - 集合工具类Collections

Java中的Collections是一个工具类,提供了一系列静态方法,用于操作集合(Collection)和Map。它包含了许多常用的方法,例如排序、查找、替换、复制等。Collections类的方法大多数都是静态的,可以直接通过类名调用,不需要实例化。它提供了许多方便的方法,使得我们可以轻松地对集合进行操作。

weixin_73869209的博客 6303

Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

🟢 Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 6万+

【Java集合】HashMap源码深度分析

本文将通过Debug流程分析,解读HashMap类的底层源码。在之前我写了一篇HashSet的源码分析,而HashSet的底层其实就是HaspMap,只不过HashSet是单列集合,所以相当于只使用了HashMap的key(键),而没有使用value(值)罢了。所以,强烈建议看本文之前对于HashSet的源码比较了解或者看过我的这篇博文:【Java集合】HashSet源码深度分析-优快云博客本篇博文是对单列集合Set的实现类HashSet的内容补充。

m0_55908255的博客 1237

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

自我改进AI:小参数编码模型如何超越GPT-5?

在人工智能领域,大模型的参数规模常被视为能力上限的决定因素。然而,一种名为自我改进AI的训练范式正在打破这一认知。它通过“生成—执行—筛选—再训练”的闭环,让模型利用编译器、测试用例等环境反馈自动生成高质量训练数据,无需昂贵的人工标注。基于该方法,一个参数量比主流大模型少117倍的编码模型,在特定基准上达到了93.3%的正确率,甚至宣称超越GPT-5默认表现。这一技术价值在于,它证明了环境反馈可以替代人工标注,让更小、更可控的模型在垂直任务中逼近甚至超越通用大模型。在代码生成、SQL生成、算法推理等结果可自

congji3817的博客 460

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java HashMap集合深度分析

在Java的全世界里,无论是类仍是各种数据,其构造的处置是整个程序的逻辑以及性能的要害。因为本人接触了一个相关性能与逻辑与此同时依存的问题,于是就开始研究这方面的问题。找遍了大大很小论坛,也把《Java 杜撰机轨范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到良好的答案

liangdiwei1的专栏 346

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

源码分析_Java HashMap源码深度分析

在java语言中,HashMap是一个非常重要的数据结构,它被广泛用于存储具有key-value映射关系的数据,HashMap提供了高效的数据结构来实现key-value的映射;从HashMap的设计与实现中,我们可以学到很多巧妙的计算机思维,对我们日常工作中进行编码及方案设计存在很高的参考价值,学习和掌握HashMap就成了非常有必要的一件事情了。 学习HashMap,有...

weixin_36138385的博客 340

Java中对HashMap的深度分析与比较Java中对HashMap的深度分析与比较

        在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java 虚拟机规范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到

JAVATEC - 伊艾法 [E.Alpha] 918

java HashMap 源码分析(深度讲解)

java 集合篇章——HashMap源码分析(非常详细)。

优快云 / 稀土掘金/ B站 / GitHub: Cyan_RA9 2559

java hashmap比较_Java中对HashMap的深度分析与比较

在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java 虚拟机规范》,《apress,.java.collections.(2001),.bm.ocr.6.0.shareconnector》,和《Thinking in Java》翻了也找不到很好的答案,于是...

weixin_34060561的博客 479

linux hashmap,Java中对HashMap的深度分析与比较

Java中对HashMap的深度分析与比较在Java的世界里,无论类还是各种数据,其结构的处理是整个程序的逻辑以及性能的关键。由于本人接触了一个有关性能与逻辑同时并存的问题,于是就开始研究这方面的问题。找遍了大大小小的论坛,也把《Java 虚拟机规范》,《apress,.java.collections.(2001),. bm.ocr.6.0.shareconnector》,和《Thinking ...

weixin_28811289的博客 227
上一篇: Windows下Apache与Tomcat的整合
下一篇: Java反射机制详解
java85140031
博客等级 码龄18年 34粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值