学习HashMap工作原理

本文深入探讨了HashMap的内部结构,包括数组+链表(红黑树)的存储方式,以及影响性能的关键因素如容量、加载因子和哈希冲突处理。文章还提供了HashMap使用的最佳实践,如设置初始容量和加载因子的策略,以及在多线程环境下使用ConcurrentHashMap的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap是JAVA语言中的Map接口的实现类之一,特点是插入慢、查询快,HashMap是JAVA中使用频率最高的映射(键值对)处理的数据类型。
HashMap内部默认为数组+链表(红黑树)的存储结构,数据结构如下:
HashMap工作原理
数组中每个元素称之为一个桶(bucket),每个桶中默认使用链表的方式存储键值对。
关于性能的设计
1、 容量和加载因子是影响性能的重要因素
容量是哈希表中桶的数量,加载因子是表示哈希表中元素填满的程度,容量默认值为16,加载因子默认为0.75,也就是说当元素达到16*0.75=12时,容量就需要扩容了。
2什么是哈希冲突,链表与红黑树转换
当发生键值对存在hash冲突(不同key的hash值相同)时,落在同一桶的元素会越来越多。当链表长度大于8且容量大于64时(源码中的默认值),链表会转换为红黑树,另外,当同一个桶中元素长度小于6时会转回链表结构,应避免这种来回转换。
3扩容
hashmap每次扩容都是原来的2倍,主要原因是:一方面是为了让重新计算的索引只有两种情况,一种是索引落在原位置,另外一种是在原位置再移动2次幂的位置。另外一方面是尽量把数据散列分布均匀,减少rehash。
以上这些设计都是为了解决查询,插入,删除等操作时的性能的一个折中考虑。
使用建议

1) 构造hashmap实例时就设置初始容量,建议设置为已知元素个数/0.75f+1(参考阿里的编码规范),避免扩容引起的rehash。
2) 长期留在内存的HashMap,可以降低加载因子,目的是减少hash冲突,不过会造成内存浪费(通过空间换时间)。
3) HashMap是非线程安全的,多线程并发编程情况下,会出现死循环,应使用ConcurrentHashMap代替。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值