jdk1.8
hashMap底层数据结构是数组+链表+红黑树
hashMap刚创建时数组容量是0,当调用put方法往里面放东西时,数组的长度才为16(默认大小),这样做是为了节省空间
数组的长度默认为16,当然在创建时也可以指定数组的长度,但是数组的长度只能为2的n次方,如果指定的长度是2的n次方,那创建的数组长度就是你指定的,如果不是2的n次方,那数组的长度会自动变为离你指定的数最近的,且比你的数大的那个2的n次方数,比如你指定10,那么长度为16
默认加载因子为0.75,当数组里的元素达到容量的0.75时(比如数组长度为100,此时已经有100*0.75=75个元素了),数组会进行扩容,大小为之前的2倍
数组的table里存储的是一个一个entry,也就是一个一个的键值对,调用put方法时会计算key的hash值,此时得到一个hash值:如果此时这个位置没有元素,就直接放上去;如果此时这个位置有元素,就会采用尾插法,把新的元素以链表的形式也放上去,当链表上的元素达到8个,但是数组元素没有超过64个,则数组会进行扩容,当数组上的元素超过64个时,链表就会变成红黑树,因为链表过长会影响查询效率,当红黑树上的元素小于6个时,红黑树会变成链表
jdk1.7与1.8的区别
jdk1.7底层数据结构是数组+链表,1.8是数组+链表+红黑树
jdk1.7在同一位置插入数据时用的是头插法,1.8用的是尾插法,
头插法:将新元素插入到链表的头部
尾插法:将新元素插入到链表的尾部
头插法在多线程的情况下会造成死循环,即a元素指向b元素,b元素又指向a元素
![](https://img-blog.csdnimg.cn/img_convert/c2b342ddb3d1d3cd63546f637ac0343e.png)