HashMap容器O(1)的查找时间复杂度只是其理想的状态,而这种理想状态需要由java设计者去保证。
在由设计者保证了链表长度尽可能短的前提下,由于利用了数组结构,使得key的查找在O(1)时间内完成。
可以将 HashMap分成两部分来看待,hash和map。map只是实现了键值对的存储。而其整个O(1)的查找复杂度很大程度上是由hash来保证的。
HashMap对hash的使用体现出一些设计哲学,如:通过key.hashCode()将普通的object对象转换为int值,从而可以将其视为数组下标,利用数组O(1)的查找性能。
OK,下面我们来看看HashMap中新增元素的时间复杂度。
put操作的流程:
第一步:key.hashcode(),时间复杂度O(1)。
第二步:找到桶以后,判断桶里是否有元素,如果没有,直接new一个entey节点插入到数组中。时间复杂度O(1)。
第三步:如果桶里有元素,并且元素个数小于6,则调用equals方法,比较是否存在相同名字的key,不存在则new一个entry插入都链表尾部。时间复杂度O(1)+O(n)=O(n)。
第四步:如果桶里有元素,并且元素个数大于6,则调用equals方法,比较是否存在相同名字的key,不存在则new一个entry插入都链表尾部。时间复杂度O(1)+O(logn)=O(logn)。红黑树查询的时间复杂度是logn。
通过上面的分析,我们可以得出结论,HashMap新增元素的时间复杂度是不固定的,可能的值有O(1)、O(logn)、O(n)。
二,hash碰撞问题
HashMap在put元素时,首先会计算key的hashcode,这时候不会去调用equals方法。为什么呢?因为equals方法的时间复杂度是O(n)。但是HashMap存在hash碰撞问题,最坏的情况下,所有的key都被分配到了同一个桶,这时map的put和get时间复杂度都是O(n)。
所以HashMap的设计者必须要考虑的一个问题就是减少hash碰撞。
HashMap解决哈希冲突采用的是哪种方式呢?
答:HashMap解决哈希冲突采用的是链地址法。说白了就是把冲突的key连接起来,放到桶里。当桶中的元素个数不超过6个时,以单链表的形式串起来,当桶中的元素个数超过6个时,以红黑树的形式串起来。
过上面的分析,我们可以得出结论,HashMap的hash操作的时间复杂度是O(1),HashMap的equals操作的时间复杂度是O(n)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)