核心原理及常见问题
底层数据结构
JDK7的底层数据结构是数据+链表
JDK8的底层数据结构是数组+链表+红黑树
- 链表的冲突解决方法:拉链法
- 引入红黑树的原因:链表查询的时间复杂度事O(n),红黑树查询的时间复杂度事O(logn),当链表长度较长时,查询效率低,引入红黑树可以提高查询效率
扩容机制
- 默认的初始容量时16,加载因子时0.75,当元素个数>=阈值(容量*加载因子)的时候,就会触发扩容机制
- 扩容机制:容量扩大为原来的两倍,并且重新计算每个元素的位置,将原数据迁移到新数组
- put方法的执行流程:
检查数组是否为空,为空则初始化(扩容);
计算 key 的哈希值(hash = key.hashCode() ^ (hash >>> 16)),通过 (n-1) & hash 定位数组下标;
若下标位置无元素,直接新建节点放入;
若下标位置有元素:
若节点 key 与传入 key 相等(equals 且 hashCode 相等),覆盖 value;
若节点是红黑树节点,调用红黑树插入方法;
若节点是链表节点,遍历链表:
找到相等 key 则覆盖 value;
未找到则尾插法插入新节点,插入后检查链表长度是否 ≥8,若满足则尝试转红黑树;
- 插入后检查元素个数是否 ≥ 扩容阈值,若是则触发扩容。