HashMap数据模型及源码解析

本文深入探讨HashMap在JDK7前后的数据结构,包括JDK8中链表长度超过8时转换为红黑树的设计。文章还介绍了HashMap的构造函数、put方法的流程,包括计算hash值的方法、resize扩容机制及其对hash冲突的影响。首次接触HashMap源码分析,欢迎指正。
摘要由CSDN通过智能技术生成

HashMap数据结构及源码解析

HashMap数据结构
JDK7以前hashmap结构是使用数组和链表组合的一个数据结构,在JDK8增加了一个新特性,当链表的长度大于8的时候会转化为红黑树
(增加这种特性的优势很明显,双向链表的结构如果Hash冲突很严重的话,会导致链表的长度一直增长这样大大减慢了查询的数据,
也有红黑树的劣势,在插入和删除需要进行旋转变色增加了时间和空间复杂度)。

在这里插入图片描述**hashmap 构造函数 **
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
这里只是为负载因子赋值没有做任何初始化操作
hashmap put方法
在这里插入图片描述
在这里插入图片描述
1、如果为空进行初始化 resize()
创建一个数组对象并返回
2、判断数组的位数
static final int hash(Object key) {//计算hash
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

tab[i = (n - 1) & hash]//计算数组的位置

这一块可能很多人呢会有疑问为什么这么设计,hashmap里面设计所有的数组的长度为2^n,基于此设定我们使用16来举个例子
在这里插入图片描述由上图我们可知通过&运算可以快速算出我们的数组下标,同时这里也存在一个问题我们都知道 object中返回的hash值为int ,java中int占有32个比特位,这样如果hash变化集中在比特位的头部就会导致大量的hash冲突那么通过hash的右位移和异或的组合操作能够将变化由高位降到地位,大大减少hash冲突
3、resize处理
随着hashmap中的元素增多hash冲突也越来越严重,如果里面的值超出 最高值负载因子 会触发resize 进行扩容
扩容的时候为了方便计算数组下标,我们需要在原有的容量基础之上
2,同时扩容之后就涉及hash重新计算数组位置的问题,由于我们只是在原有的基础上*2所以对应二进制需要增加一个1,也就意味原本一个hash可能拆分到两个位置上面,拆分又有两种情况 第一种:是链表的话这个比较简单。使用容量&hash 如果为0则认为处于当前位置,如果为1放到新链表。 第二种是红黑树:同样使用容量&hash,拆分后需要判断树的元素是否小于6,如果小于6就将树转化为链表

第一次写博客,根据源码和一些资料整合。。写的有问题,请联系我修改哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值