hashmap相关(记录的比较乱,也不够深入)(有想一起学习的小伙伴可以私信我)

hash三列操作

除法散列法

数组初始容量16

扩容因子:0.75

8-红黑树 泊松分布
6-链表

hashmap在new的时候没有创建数组(数组里面放的是entry对象,这里面含有key,value,next,hash),只是传了2个参数,一个16,一个0.75

如果在初始化的时候,给的数组长度为11,13,17之类的,在put的时候,会有一个转换的过程,将他转为距离它最近的2的n次幂的值

初始值设置成2的n次幂原因:1.为了方便对key的&运算,提高效率,&要比取模运算效率高,hash & (initCapacity-1)

然后再创建数组空间

对key取hash值,为了减少hash碰撞,将二进制值右移四位,散列到数组中

通过&运算,代替取模运算

hashmap 四个参数

1.默认初始容量1<< 4–16

2.容量最大值1<< 30 – 2的30次幂

3.扩容因子0.75 也就是说初始长度为16,则当长度达到16*0.75=12的时候就进行扩容,16变成32

4.链表转红黑树,长度为8,当长度>7时就进行转换 --泊松分布

5.红黑树转链表,长度为6

6.jdk1.7中,数组中放的是entry(hash,key,value),jdk1.8中是node(hash,key,value)和treeNode(left,right,red,prev,parent)

补充:无论初始容量写成多少,到hashmap中都会进行一个转换,转换成距离最近的2的n次幂,进入put()第一件事就是这个

7.1.8中的扰动函数的方式和1.7中扰动方式不一致,对key取hash值,采用key的hashcode 异或 key>>>16,这个叫扰动函数,不然在确定key的存放位置时是通过key%(数组初始长度-1),这样只有低4位参与到运算中,所以通过上面的这种方式让高位也参与到运算中,增加hash散列的程度

8.为什么容量一定是2的n次方,

  • 因为2的n次方-1后,低位都是1111,在取模运算时,取得的余数正好就是keyhash值得低4位,采用&运算,&1111,低4位的值正好就是取模的值。
  • 在进行数组扩容后,需要重新分配位置,比如扩容到了32,就是11111,只需要对比第5位的值进行&操作,如果是0,表示新数组下标不变,如果是1则将索引位置加上旧的数组长度即可
  1. 1.7中扩容后链表采用尾插法,16-28-32变成32-28-16,1.8采用头插法

具体执行过程,见牛客网上的详解,已收藏

主要区别:1.扰动函数扰动次数不同,1.7扰动了6次,1.8扰动了2次
2.1.8中如果产生hash冲突,先是链表,后是红黑树

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值