【HashMap全面知识点】— 快速理解HashMap

目录

一、核心概念

1.定义

2.核心参数

二、底层数据结构与演进

结构细节:

三、核心算法与实现

1.哈希值计算

2.索引计算

3.put方法流程(JDK 1.8)

4.扩容(resize)机制

四、JDK 1.7 与 JDK 1.8 核心差异

五、并发隐患与解决方案

1.并发问题

2.解决方案

六、高频面试题

1.HashMap与Hashtable的区别?

2.为什么容量必须是2的幂?

3.HashMap中Key可以是任何对象吗?

4.HashMap迭代器的fail-fast机制?

5.红黑树转换条件?

七、实践建议

一、核心概念

1.定义

实现Map接口,用于存储键值对(key-value),允许null键(仅一个)和null值,非线程安全,元素无序(插入顺序与遍历顺序不一致)

2.核心参数

  • capacity:哈希桶数组容量(默认16,必须为2的幂,最大2³⁰)
  • LoadFactor:负载因子(默认0.75),衡量数组填充程度(填充程度=实际元素数量(size)/数组容量(capacity))
  • threshold:扩容阈值(capacity*LoadFactor),元素数量超过此值时触发扩容
  • size:实际存储的键值对数量

举例:

        当数组容量为 16,负载因子 0.75 时,扩容阈值 = 16 × 0.75 = 12

        当元素数量达到 12 时,填充程度 = 12/16 = 0.75,此时触发扩容(容量变为 32),避免填充程度过高导致性能下降

二、底层数据结构与演进

版本 数据结构 红黑树支持 链表插入方式
JDK 1.7 数组+单向链表 不支持 头插法
JDK 1.8 数组+单向链表+红黑树 支持 尾插法

结构细节:

  • 哈希桶数组(table):存储节点的数组,每个元素是链表或红黑树的头结点
  • 链表:解决哈希冲突,相同索引的元素以链表形式存储
  • 红黑树:JDK 1.8 新增,当链表长度>=8且数组容量>=64时,链表转为红黑树查询(时间复杂度从O(n)优化为O(logn));当节点数<=6时,红黑树转为链表

三、核心算法与实现

1.哈希值计算

JDK 1.8 对hashCode()进行二次处理,增强随机性

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 高16位与低16位异或
}

2.索引计算

通过哈希值与数组长度减一的与运算确定索引

int index = (table.length - 1) & hash; // 等价于 hash % table.length(
哈希表(HashMap),在Java中通常是`java.util.HashMap`,是一种常用的数据结构,它使用哈希算法来存储和检索数据。这里有一些关键知识点: 1. **基础概念**: - 哈希表基于哈希函数创建索引,通过键(key)快速定位到值(value)。 - 每个键值对由一个键和对应的值组成,键必须唯一。 2. **性能**: - 插入、删除和查找操作的时间复杂度通常为O(1),但在最坏情况下可能达到O(n)(当哈希冲突严重时)。 - 哈希冲突是指不同的键产生了相同的哈希值。解决冲突的方式有链地址法(使用单链表)或开放寻址法(如线性探测)。 3. **内部实现**: - 使用数组存储元素,每个数组元素称为桶(bucket),实际存储的是链表或红黑树(取决于是否超过负载因子)。 - 当插入新元素时,计算键的哈希值,然后根据该值决定元素在哪个桶中。 4. **扩容**: - 如果哈希表接近其容量限制(默认为0.75 * 原容量),它会自动进行扩容,增加新的数组空间,并重新哈希所有元素。 5. **注意事项**: - 不保证顺序访问:HashMap不是有序的,如果需要保持插入顺序,可以考虑使用LinkedHashMap。 - 键不能为null:键不能为空,但值可以为null。 - 并发处理:虽然HashMap是非同步的,但如果需要支持并发,可以使用ConcurrentHashMap。 6. **典型用法**: - 存储和获取数据,适用于查找频繁的场景。 - 缓存:由于查找速度快,HashMap常用于缓存实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值