HashMap三个重要的方法
一级目录
二级目录
三级目录
这里没有源码 但是HashMap的学习必须看源码,建议与学习总结同时观看
HashMap 第一个重要方法:新增方法
get方法,
1.根据传入key和通过key获取哈希值,
2.对第一个节点做非空判断
比较map第一个元素的哈希值是不是和传入的值一样,如果是就返回,
4.不是就查找下一个节点 如果结构是
如果是树,就采用红黑树查找,如不是树结构,极有可能是链表,就循环判断
put方法
(通过哈希值获取key在数组中的位置的计算)
1.调用哈希函数,让hashcode的16位与低16位做异或运算,得到哈希值
从效率考虑,让高位与低位都能参与哈希函数的计算
为了让元素在map中均匀分布
对象的hashcode方法
hash&(数组长度-1)
相当于
hashcode%数组长度
目的:为了让哈希表里的第一个元素均匀一些
这也可以解释容量总是为2的n次方,这样每次我都可以通过hash&(length-1)计算hashmap1的位置
扩容
阈值 比如默认长度16*负载因子0.75 已经用的容量超过12——》扩容
这块我可以简单说一下1.7和1.8的区别,1.7扩容后每个节点采用头插法,容易产生一个问题就是造成我在resize调用transfer(赋值到新数组的方法)的时候,造成一个死循环
1.8改进以后就是没用了transfer方法,他是这么一个流程
1.计算新桶数组的容量 newCap 和新阈值 newThr,这部分他的最大值是2的31次方-1,不能再多。如果是在16到2的30次方之间,扩大两倍
2.计算完新阈值和新容量之后,就重新分配元素了分三种
2.1只有一个元素,直接插入
2.2如果是红黑树,就split方法分配
3.3链表的话,就是通过oldcap与哈希做与运算,来判断扩容后要不要移动,如果觉得他需要移动,就是在原来的位置上+原来哈希表的长度
扩容是对他进行重新new一个数组,用一个新的桶
1.8对他继续优化,扩容不是重新计算每个下哈希值,而是通过oldcap与哈希做与运算,来判断扩容后要不要移动
1.7相比1.8的扩容优化
扩容后红黑树的移动是比较方便的,通过上面的与运算,如果觉得他需要移动,就是在原来的位置上+原来哈希表的长度