目录
一、核心概念
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(

最低0.47元/天 解锁文章
815

被折叠的 条评论
为什么被折叠?



