Java HashMap

数据结构:

  • 是一个经典的哈希表的实现.
  • Java7 哈希桶+链表
  • Java8 哈希桶+链表+红黑树
  • 插入/查找/删除操作时间复杂度是O(1)
  • 缺陷:哈希值的碰撞(退化链表)
    在这里插入图片描述

Java7 版本

数据结构:哈希桶+链表
初始容量(16)
负载因子(0.75 四分之三)
哈希算法(根据hashCode值计算出放到哪个哈希桶里面,防止碰撞)
扩容:容量达到负载就会触发扩容,变为原来的两倍,重新哈希计算将原有的元素重新分配

缺陷:

  1. 非常容易碰到死锁,链表死循环(扩容后链表顺序会反转,并发容易导致链表成环 酷壳-hashmap 文章)
  2. 哈希值的碰撞:如果恰巧每个值都挂在同一个哈希桶的时候,hashmap就会退化成一个链表
    (有个安全漏洞,tomcat将http参数用hashmap存储,黑客可以精心构造一个请求参数,使得所有的参数哈希值都一样,一次让hashmap退化成链表,消耗系统cpu 漏洞名:CVE-2011-4858

Java8 版本

数据结构:哈希桶+链表+红⿊树
大幅度减轻线程安全问题:扩容时使用与插入顺序一致的方法

考点:

为什么容量是2的幂?

  1. 方便将哈希值映射到桶的编号 hash&(size-1) 容量减一后二进制数后面全是1,方便与哈希值&(按位与)后快速得到桶的编号
    在这里插入图片描述

  2. 方便扩容原先的元素要么保持不变,要么被移动到旧index+旧桶大小的位置上

一个对象是如何被映射到哈希桶的?

hashCode -> rehash -> index

HashMap的容量/负载因子/变树的阈值/恢复成链表的阈值

初始16,永远2的幂/0.75(四分之三)/8/6

Java8的实现中HashMap 哈希桶里面的链表什么时候会变成红黑树?

当前桶容量大于8并且哈希桶数量超过64位的时候,小于等于6会转化回来
在这里插入图片描述
大于8 源码

在这里插入图片描述
小于等于6源码

在这里插入图片描述

Java8对Java7进⾏了什么改进?

更好的处理哈希碰撞(效率)
改进了扩容时的插⼊顺序(安全性)

线程安全问题?

Java7存在,Java8被大幅度减轻

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值