JDK1.7 HashMap主要是由数组和链表组成的。扩容时用的是头插法 (A > B > C)(C > B > A)
JDK1.8 HashMap主要是由数组和链表加红黑树组成的。扩容时改成了尾插法 (A > B > C)(A > B > C)
它不是线程安全的。核心的点就是put插入数据的过程,get查询数据以及扩容的方式。
Put 插入数据流程
往map插⼊元素的时候⾸先通过对key hash然后与数组⻓度-1进⾏与运算((n-1)&hash),都是2的次幂所以等同于取模,但是位运算的效率更⾼。找到数组中的位置之后,如果数组中没有元素直接存⼊,反之则判断key是否相同,key相同就覆盖,否则就会插⼊到链表的尾部,如果链表的⻓度超过8,则会转换成红⿊树,最后判断数组⻓度是否超过默认的⻓度*负载因⼦也就是12,超过则进⾏扩容。
Get查询数据
查询数据相对来说就⽐较简单了,先计算出hash值,然后去数组查询,是红黑树就去红黑树查,链表就遍历链表查询就可以了。
Resize扩容过程
扩容的过程就是对key重新计算hash,然后把数据拷贝到新的数组。