1、 hashMap是基于Map接口的非同步实现(同步就是一个对象只能一个线程访问),它是以Key-value键值对的形式(封装成Node对象)存取数据的,线程不安全的集合,允许null键和null值,只能一个null键,但是可以有多个null值。
JDK7之前是数组+链表的形式(数组的每个位置都存储一个单向链表),JDK8后是数组+链表+红黑树的形式(链表的数据达到一定的阙值(8)就会转换成红黑树)。
容量:哈希表中数组的数量,默认初始容量是16(必须的2的倍数,提高计算机的执行效率)
加载因子:默认值为0.75
扩容阙值:容量*加载因子
非同步实现,底层通过一个modCount记录修改的次数,修改后回增加modCount
值,迭代器初始时会把modCount值赋值给exceptedModCount,在迭代的过程中,如果二者的值不一样,则报异常。
2、hashMap的put方法:
重新计算hash值:拿到 key 的 hashcode 值之后,调用 hash() 方法重新计算 hash 值
计算元素存放在数组的哪个位置:将重新计算出来的 hash 值与 (tablel.length-1) 进行位与&运算,得出元素应该放入数组的哪个位置
将key-value添加到数组中: 1.如果计算出的数组位置上为空,那么直接将这个元素插入放到该位置中 2.如果数组该位置上已经存在链表,则使用 equals() 比较链表上是否存在 key 相同的节点,如果为true,则替换原元素;如果不存在,则在链表的尾部插入新节点(Jdk1.7及以前的版本使用的头插法)3.如果插入元素后,如果链表的节点数是否超过8个,则调用 treeifyBin() 将链表节点转为红黑树节点 4.最后判断 HashMap 总容量是否超过阈值 threshold,则调用 resize() 方法进行扩容,扩容后数组的长度变成原来的2倍