HashMap在JDK1.8之前:底层实现是数组+链表,扩容机制是当table中元素的个数已经达到阈值(table.length*0.75)时扩容。
- 1)先计算key的hashCode值
- 2)根据key的hashCode值再与数组table的长度做一个运算(%或&),得到一个索引位置index,决定它在table那个元素(桶)下面。
- 3)如果table[index]是空的,把映射关系构建为一个Entry(Entry是实现了Map.Entry类型)的对象,直接放进去
- 4)如果table[index]不是空的,判断table[index]的元素的key与我们新的key调用equals方法是否相等,如果相等,替换
- 5)如果table[index]不是空的,判断table[index]的元素的key与我们新的key调用equals方法全部都不相等,判断是否table中元素的个数已经达到阈值(table.length*0.75),如果已经达到,先扩容,回到(2)否则就构建一个Entry的对象,连接到链表的上面。
HashMap在JDK1.8之后:底层实现是数组+链表/红黑树,扩容机制
- (1)先计算key的hashCode值
- (2)根据key的hashCode值再与数组table的长度做一个&运算,得到一个索引位置index,决定它在table那个元素(桶)下面。
- (3)如果table[index]是空的,把映射关系构建为一个Node(Node是实现了Map.Entry类型)的对象,直接放进去
- (4)如果table[index]不是空的,判断table[index]的元素的key与我们新的key调用equals方法是否相等,如果相等,就用新的value替换旧的value;
- 如果都不相等,再继续看
A:如果table[index]下面已经是一棵红黑树,那么直接把映射关系构建为一个TreeNode(TreeNode是Node的子类)的对象,放到某个叶子节点上
B:如果table[index]下面不是一棵红黑树,那么就又要判断它下面的链表的元素个数是否达到8个:- 如果没有到达8个,那么直接把映射关系构建为Node的对象,直接连接到链表的下面。
- 如果已经达到8个,那么就再次判断table.length是否达到64,如果没有达到64,先扩容,回到(2)。如果已经达到64,就把该链表变成一颗红黑树,然后把新的映射关系构建一个TreeNode对象,放到某个叶子节点上。
- 如果都不相等,再继续看
- (5)如果添加后size达到阈值(table.length*0.75),要扩容重写调整所有元素的位置。