HashMap知识小结

1、HashMap的put过程

  1. 首先根据key值计算hash值,找到该元素在数组中存储的下标
  2. 如果数组是空的,则调用resize进行初始化
  3. 如果没有哈希冲突直接放在对应数组下标里
  4. 如果冲突了,且key已经存在,就覆盖掉value
  5. 如果冲突后是链表结构,就判断该链表是否大于8,如果大于8并且数组容量小于64,就进行扩容;如果链表节点数量大于8且数组的容量大于64,则将这个结构转换成红黑树;否则,链表插入键值对,若key存在,就覆盖掉value
  6. 如果冲突后,发现该节点是红黑树,就将这个节点挂在树上

2、HashMap的容量为什么必须是2的次方数

  • 计算索引位置的公式为(n-1)& hash值,n就是hash表长度,当n为2的N次方数时,n-1的低位全是1,此时任何hash值和n-1进行&运算的结果为该hash值的低位,如果n不是2的次方数,则&操作后计算出的地址hash冲突的几率会很大,例如:当hash表长度为6时(不是2的幂次方),5按位与后为5,但7与5按位与后结果也是5,导致hash冲突(因为hash值是唯一的,所以按位与后对原hash的低位计算后不改变是最优解)

3、 HashMap1.7计算哈希码为什么要同时用到高低位?

  • 如果hash表的长度较小,则让高位也参与运算无伤大雅,并不会有太大开销,因为位运算性能很高,但是,若不加入高位运算的话,则结果只取决于低位,无论高位怎么变,结果都一样,如果加入高位运算,则索引计算结果就不会仅取决于低位,进一步降低了hash冲突的发生

4、 在HashMap中同一个桶位中的元素,哈希码都是一样的吗?为什么?

  • 大多数情况下是不一样的,因为hashmap中的哈希函数也叫散列函数,它的目的就是让hashmap中的对象散列分布,所以2个不同的对象产生相同的hashcode的概率是很低的

5、 在HashMap扩容时,同一个桶位中的元素会被分配到新数组中的什么位置,为什么?

  • hashMap扩容后,变为原hash表长度的两倍,即假设原表长度为:16,则扩容后的长度为32,按照索引地址计算公式(n-1)& hash,同一桶位有两个元素分别是hash值为1和hash值17,它们计算索引地址后结果一样,所以放在了一个桶位,在扩容后,hash值为1的位置不变,hash值为17的位置变为17

  • 桶位中只有一个节点时,新位置就是hash &(新表长度-1),桶位中有多个节点时,判断hash&旧表长度 ==0 ,如果为true,则在新表中与旧表中的位置一样,为false时,位置为旧表位置+旧表容量

    为什么红黑树和链表都是通过 e.hash & oldCap == 0 来定位在新表的索引位置?

    • 假设a、b节点在同一索引位置,table容量为16,扩容后变为32,新表的n-1只比旧表在高位多了一个1,所以在计算新表索引位置时,只取决于在新表高位多出来的这一位,(低位都是一样的)且这一位的值刚好等于旧表长度(oldCap)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值