0
点赞
收藏
分享

微信扫一扫

HashMap在JDK1.7和1.8里的区别是什么

干自闭 2022-04-16 阅读 75

HashMap

  1. get和put的时间复杂度为O(1)
  2. 为了解决hash冲突,HashMap引入了链表
  3. 计算数组下标并不是用取模,而是用位运算 hashcode&(length-1),位运算效率>取模,因为位运算是最接近于机器所能识别的运算,cpu二进制
  4. hashmap默认扩容因子0.75,扩容阈值:16*0.75,最大容量2的30次方, 初始容量2的4次方即16
  5. 默认初始容量16,如果自定义初始容量必须是2的指数幂,如果不是,则强行转换为大于这个数的2的最小指数幂。
  6. HashMap是线程不安全的,不安全的具体原因就是在高并发场景下,扩容可能产生死锁(Jdk1.7存在)以及get操作可能带来的数据丢失。

为什么要转换成2的指数幂?

        减少哈希碰撞,为了让哈希结果更加散列。hashcode&(length-1),hashcode会进行一些异或运算(扰动计算),让哈希散布的更加均匀,尽量减少哈希碰撞。

hashcode&(length-1)?

        长度为什么要减1,不减1的话&操作之后只有两种结果,要么为1要么为0。

扩容以后旧数组往新数组迁移会有问题?

        多线程下链表成死环的问题

1.8jdk的hashmap为什么链表长度>=8转换为红黑树,为什么是8呢?

        长度为8时

JDK1.7

  1. 底层实现:数组+链表,数组作用:时间复杂度O(1),链表作用:解决哈希冲突
  2. 头插法,整体下移

JDK1.8

  1. 引入红黑树,链表长度>8且数组长度>=64转换为红黑树,否则优先扩容
举报

相关推荐

0 条评论