回答
HashMap 是一种存取高效但不保证有序的常用容器。它的数据结构为“数组+链表”,是解决哈希冲突的产物,也就是我们常说的链地址法。它实现了Map 接口采用K-V 键值对存储数据,并实现了浅拷贝和序列化。
HashMap 的默认初始大小为16,初始化大小必须为2的幂,最大大小为2的30次方。数组中存储的链表节点Entry 类实现于Map.Entry 接口,它实现了对节点的通用操作。
HashMap 的阈值默认为“容量*0.75f”,当存储节点数量超过该值,则对map 进行扩容处理。
HashMap 提供了4种构造方法,分别是默认构造方法;可以指定初始容量的构造方法;可以指定初始容量和阈值的构造方法以及基于一个Map 的构造方法。虽然是构造函数,但是真正的初始化都是在第一次添加操作里面实现的。
在第一次添加操作中,HashMap 会先判断存储数组有没有初始化,如果没有先进行初始化操作,初始化过程中会取比用户指定的容量大的最近的2 的幂次方数作为数组的初始容量,并更新扩容的阈值。
接着添加操作讲解。添加操作的执行流程为:
- 先判断有没有初始化
- 再判断传入的key 是否为空,为空保存在table[o] 位置
- key 不为空就对key 进hash,hash 的结果再& 数组的长度就得到存储的位置
- 如果存储位置为空则创建节点,不为空就说明存在冲突
- 解决冲突HashMap 会先遍历链表,如果有相同的value 就更新旧值,否则构建节点添加到链表头
- 添加还要先判断存储的节点数量是否达到阈值