HashMap源码解读


提示:个人笔记,下面案例可供参考

HashMap(线程不安全):默认容量是16,加载因子是0.75,每次扩容 容量会增张两倍
JDK1.7:数组+链表:
JDK1.8:数组+链表+红黑树
链表长度大于8并且数组长度大于64 会变成红黑树

1.HashMap初始化容量为什么要2的幂次方?

计算流程:
1.会根据hashMap的key值获取hash值.
2.传入的初始化值减1与hash值进行’与‘运算.
3.计算出的结果为数组角标
1.1初始值不为2的幂次方时:

假设n为14,n-1的二进制为0000 1101,与hash值运算结果如下
在这里插入图片描述

假设n为13,n-1的二进制为0000 1100,与hash值运算结果如下
在这里插入图片描述
*可以看到这样会增加hash碰撞的几率(计算出的结果一样)


1.2初始值为2的幂次方时

假设n为16(2的幂次方),n-1的二进制位0000 1111,与hash值运算结果如下
在这里插入图片描述

假设n为8(2的幂次方),n-1的二进制位0000 1111,与hash值运算结果如下
在这里插入图片描述


2.将链表转换为红黑树

1.根据哈希表中元素个数确定是扩容还说树形化。
2.如果是树形化遍历桶中的元素,创建相同个数的树形节点,复制内容,建立联系。
3.然后让桶中的第一个元素指向新创建的树根节点,替换桶的链表内容为树形化内容。

3.HashMap扩容机制

1.当HashMap中的元素个数超过了数组大小(数组长度*负载因子)时,就会进行扩容。默认情况下,数组大小为16,那么当HashMap中的元素个数超过了16×0.75(默认)时,就会把数组的大小扩展为2×16=32,即扩大了一倍,然后诚信计算每个元素在数组中的位置。
2.当HashMap中的其中一个链表的对象个数如果达到了8个,此时如果数组长度没有达到64,那么HashMap会先扩容解决,如果已经达到了64,那么这个链表会变成红黑树,节点类型由Node变成TreeNode类型。如果树节点个数小于6时,会再把树转为链表。
3.扩容之后的节点要么就在原来的位置,要么就被分配到“原位置+旧容量”这个位置上。
4.在扩容HashMap的时候,不需要重新计算hash,只需要看看原来的hash值新增的那个bit是1还是0就可以了,是0的话索引没变,是1的话索引变成“原位置+旧容量”。

在这里插入图片描述

4.如何设置HashMap的初始化问题描述

1.我们想要在代码中创建一个HashMap的时候,如果我们已知这个map中即将存放的元素个数,给HashMap设置初始容量可以在一定程度上提升效率。公式:“所需要的使用个数/0.75+1“。
2.JDK并不会直接拿用户传进来的数字当默认容量,而是会进行一番运算,最终得到一个2的幂次方(3->4 ,7->8 ,9->16)。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值