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

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转换为红黑树,否则优先扩容。为什么要把长的链表转换成红黑树呢,因为插入操作在查找的过程中用了一个 for 循环找到尾部,时间复杂度是O(n),而红黑树可以让搜索的复杂度降到O(logn)
  2. 尾插法(解决1.7下多线程插入死循环的问题),高低位指针。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值