HashMap源码解读

1. HashMap概述

HashMap是基于哈希表的Map接口实现,允许空键和空值。它继承自AbstractMap,实现了MapCloneableSerializable接口。

2. 底层数据结构

在JDK 1.8中,HashMap的底层数据结构由数组 + 链表 + 红黑树构成:

  • 数组:存储哈希表的节点(Node)。

  • 链表:解决哈希冲突,当多个键的哈希值相同或相近时,它们会被存储在同一个数组槽位的链表中。

  • 红黑树:当链表长度超过一定阈值(默认为8)时,链表会被转换为红黑树,以提高操作效率。

3. 构造函数

HashMap提供了多个构造函数,最基础的构造函数如下:

public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}
  • initialCapacity:初始容量,决定了哈希表的初始大小。

  • loadFactor:加载因子,用于控制哈希表的扩容。

4. 关键方法解析

4.1 put()方法

put()方法用于将键值对插入到哈希表中:

  1. 计算哈希值:通过hash()方法计算键的哈希值。

  2. 定位数组槽位:通过(n - 1) & hash计算键在数组中的位置。

  3. 处理冲突:如果槽位已有数据,通过链表或红黑树解决冲突。

  4. 扩容:如果哈希表中的元素数量超过阈值,会触发resize()方法进行扩容。

4.2 get()方法

get()方法用于根据键获取值:

  1. 计算哈希值:通过hash()方法计算键的哈希值。

  2. 定位数组槽位:通过(n - 1) & hash找到键所在的数组槽位。

  3. 查找键值对:在链表或红黑树中查找键对应的值。

4.3 resize()方法

resize()方法用于扩容哈希表:

  1. 创建新数组:创建一个容量为原数组两倍的新数组。

  2. 迁移数据:将原数组中的数据迁移到新数组中。

  3. 更新阈值:更新扩容阈值为新数组容量与加载因子的乘积。

5. 哈希冲突处理

HashMap通过以下方式处理哈希冲突:

  • 链表:当多个键的哈希值相同或相近时,它们会被存储在同一个数组槽位的链表中。

  • 红黑树:当链表长度超过8时,链表会被转换为红黑树,以提高操作效率。

6. 性能优化

HashMap通过以下方式优化性能:

  • 负载因子:通过设置合适的负载因子,控制哈希表的扩容时机,避免过度扩容。

  • 即时编译(JIT):JVM的即时编译器会优化HashMap的热点代码,提高执行效率。

7. 线程安全性

HashMap是非线程安全的,多个线程同时操作HashMap可能会导致数据不一致。如果需要线程安全的哈希表,可以使用ConcurrentHashMap

8. 总结

  • 底层数据结构:数组 + 链表 + 红黑树。

  • 关键方法put()get()resize()

  • 哈希冲突处理:链表和红黑树。

  • 性能优化:负载因子和即时编译。

  • 线程安全性:非线程安全,推荐使用ConcurrentHashMap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十五001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值