【 Java HashMap的实现原理?】

Java HashMap的实现原理

概述

  • HashMap是基于哈希表的Map接口的非同步实现。
  • 它允许使用null值和null键。
  • HashMap不保证映射的顺序,特别是它不保证该顺序恒久不变。
  • HashMap假定哈希函数将元素适当地分布在各桶之间,为get和put操作提供稳定的性能。

数据结构

  • HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
  • 在JDK 1.7及之前,HashMap底层是一个数组+链表结构。
  • 在JDK 1.8及之后,HashMap引入了红黑树以优化性能。当某个桶(数组的一个位置)的链表长度大于等于8并且HashMap的数组长度大于等于64时,链表会转换为红黑树。

哈希冲突处理

  • 当两个或多个键的哈希值相同时,会发生哈希冲突。
  • HashMap使用链地址法(Chaining)来处理哈希冲突。这意味着当冲突发生时,冲突的键值对会被存储在同一个桶的链表中(或红黑树中)。

存储与查找

  • 当存储一个键值对时,首先根据键的哈希值找到对应的桶。
  • 如果桶为空,则直接将键值对插入桶中。
  • 如果桶非空,则遍历桶中的链表或红黑树:
    • 如果键已经存在,则替换其值。
    • 如果键不存在,则将键值对插入链表或红黑树的末尾。
  • 查找操作与存储操作类似,也是根据键的哈希值找到对应的桶,然后遍历链表或红黑树来找到对应的值。

扩容机制

  • HashMap在创建时可以指定初始容量和加载因子。
  • 当HashMap中的元素数量超过初始容量乘以加载因子时,会进行扩容。
  • 扩容时,HashMap的容量会变为原来的两倍,并重新计算所有元素的哈希值以重新分布到新的桶中。

性能特点

  • 由于HashMap使用了哈希表和链表(或红黑树)的结合,因此它在大多数情况下提供了接近O(1)的插入、获取和删除性能。
  • 但需要注意的是,HashMap的性能受到哈希函数质量、加载因子和初始容量的影响。

注意事项

  • HashMap不是线程安全的。如果多个线程同时访问一个HashMap,并且至少有一个线程从结构上修改了它(即添加或删除了一个或多个映射关系),则必须在外部保持同步以防止意外的非同步访问。

补充概念:加载因子

加载因子(Load Factor)是HashMap中的一个重要参数,用于确定HashMap的扩容阈值。以下是关于加载因子的详细解释:

  • 定义:
    加载因子是一个浮点数,用于控制HashMap的扩容行为。它决定了HashMap在其容量自动增加之前可以达到多满的一种尺度。
  • 计算公式:
    加载因子 = 元素个数 / 容量
    当HashMap中的元素个数超过容量与加载因子的乘积时,即达到了扩容阈值,HashMap会进行扩容操作。
  • 默认值:
    在Java中,HashMap的默认加载因子是0.75(即75%)。
    默认初始容量是16,因此默认的扩容阈值是 16 * 0.75 = 12。也就是说,当HashMap中的元素个数达到12时,它会进行扩容操作。
  • 作用与影响:
    加载因子的选择是一个权衡的结果,它既要保证HashMap的性能又要节约内存空间。
    较低的加载因子可以减少哈希碰撞的概率,提高HashMap的性能,但会增加扩容的频率,从而增加时间开销和内存使用。
    较高的加载因子可以节约内存空间,减少扩容的频率,但会增加哈希碰撞的概率,降低HashMap的性能。
  • 自定义:
    HashMap允许用户自定义加载因子。在创建HashMap时,可以通过构造函数指定初始容量和加载因子。
    例如:HashMap<K, V> map = new HashMap<>(int initialCapacity, float loadFactor);
  • 总结:
    加载因子是HashMap中的一个重要参数,用于控制HashMap的扩容行为。
    它通过权衡性能和内存使用来确定HashMap何时进行扩容操作。
    默认的加载因子是0.75,但用户可以根据具体的应用场景和需求进行自定义。
  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值