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的位置

HashMap三个重要的方法

扩容

阈值 比如默认长度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的扩容优化

扩容后红黑树的移动是比较方便的,通过上面的与运算,如果觉得他需要移动,就是在原来的位置上+原来哈希表的长度