jdk1.7之HashMap


HashMap是用于存储Key-Value键值对的集合, 每一个键值对也叫作一个Entry。所以HashMap底层是由数组加单向链表构成的, 默认的初始长度为16, 每次自动扩容或是手动初始化时候长度必须是2的幂;

 

为什么初始化长度为16 ?

 

Return  h & (length - 1);

下面我们以“book” 作为key演示一下: book通过 hashCode,十进制结果为3029737,二进制101110001110101110 1001,
通过  & 运算默认长度为16 ,length – 1 就是 15, 转换为二进制 1111 ,

101110001110101110 1001 & 1111 = 1001,十进制是9, 所以index = 9 ,

 

假设HashMap长度为10 重复上面的运算步骤

hashCode : 101110001110101110 1001
length–1 :                    1001
index   :                     1001

单独看这个结果, 从表面上看没有什么问题, 换一个数试一下

hashCode : 101110001110101110 1011
length – 1 :                  1001
index   :                     1001

这里就能看出, 虽然hashCode数变化的但是当长度为为10的时候结果都是为1001,这样就会造成index结果出现几率变大, 而有些index的结果永远不会出现,比如说0111;

 

反过来看 16或者是2的幂的数值, length – 1 的值转换为二进制全部都是1, 只需要hashCode本身计算的值比较均匀, 那么Hash算法的结果就是均匀的;

 

HashMap是怎么扩容的?


在高并发情况下, 首先要明白 ReHash 的概念

 

ReHash其实就是HashMap在扩容时候的一个步骤

 

HashMap的容量是有限的, 当经过多次元素插入达到扩容因子0.75时候就会扩容, 这个时候就会扩容就是 resize

影响发生resize的元素有两个:

1.     Capacity  指的是当前hashMap的长度;

2.     LoadFactor 负载因子, 默认是0.75

上图if判断里面 HashMap.Size   >= Capacity * LoadFactor

 

HashMap的resize方法不是简单的把长度扩大,而是经过了两个步骤

1.     扩容创建一个新的Entry数组, 长度是原来的两倍

2.     ReHash 遍历原来的Entry数组, 把原数组所有的的值重新导入新的Entry数组中

 

HashMap为什么是线程不安全的






在单线程下扩容是没有问题的, 但是在多线程并发环境中,HashMap的ReHash操作就会带来问题

详细可见  :  https://www.jianshu.com/p/1e9cf0ac07f4

 

for循环循环的是当前的数组,

 

 

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值