JDK1.7,1.8 hashmap实现原理

JDK1.7,1.8 hashmap实现原理

1.7版本 的Hashamap使用的是数组+链表实现
1.8版本的hashmap使用的是数组+链表+红黑树实现

我们首先要知道2个问题:
1)为什么我们的HashMap在扩容的时候都是原来容量的2倍,既2的n次方。
因为HashMap在计算存储对象的下标时 会使用key的hash值 与上 容量-1 ,那么当int类型数据做与运算时是通过二进制来进行的,打比方 这里 key的哈希值转化为二进制是0001 1001 (实际应该是32位,这里取后8位的值) ,而如果此时hashmap的容量(size)为16 则 容量的二进制是 0001 0000,在HashMap获取下标的方法中 (size-1) & hash
则:
hash : 0001 1001
16 : 0001 0000
15: 0000 1111
hash与15做与运算,相同的位置如果都是1 则为1 反之则为0
最终的结果是: 0000 1001 ---- 得到的数组下标为9
这个插入的值会放到数组下标为9的位置

这时会有2种情况:
在数组为9的位置里面有没有值?
情况1,如果有: 我们会判断 我们插入的hash值,key值 是否和已有值是相等的,如果相等,新插入的value值会替换oldVaule值,并且将oldValue值返回;如果不想等,我们会使用链表的头插式,将新插入的元素加到已有值的上方,并且向下推移(实现的原理是

Public Class Node(){
	private Object constant; //链表的实体
	private Node next; //表示下一个节点
	public Node(Object constant,Node next){
		this.constant = constant;
		this.next = next;
	}
	public static void main(String[] args){
		new Node(new Object,null);//表示这个节点为链表的第一个节点
	}
}

);

2)为什么在HashMap的源码中 我们会将获得到的哈希值向右进行偏移?
这个是因为哈希碰撞的问题,那么什么是哈希碰撞呢?

1.7 当我们使用HashMap存储数据时的api是

HashMap map = new HashMap();
	map.put("1","张三");
	map.put("2","李四");

其中“1”是key “张三”是value;
HashMap的put方法会先把“1”.hashCode 转化为哈希值,比如说是
1001 0011 1010
其中“2”是key “李四”是value;
HashMap的put方法会先把“1”.hashCode 转化为哈希值,比如说是
0000 0011 1010
上面我们说过的hash与上容量来获得下标 最终这2个元素的下标都会是 1010 既是10
那么这个就是哈希碰撞,我们通过把张三的hash二进制的值
1001 0011 1010 想右偏移 4位
0000 1001 0011 1010
然后将最右边的1010去掉
0000 1001 0011
这个时候再进行获取下标操作,可以发现这次2个元素的下标不一样了,这个避免了我们在数组的同一个下标上,链表元素过多的情况;

再说到1.7的扩容;
JDK默认的加载因子是0.75
以默认的容量大小16为例子,如果HashMap中entry超过12,既16×0.75=12,时会扩容为32;这里有一个规律,我们在数组下标为9的地方存储的数据可能还在9的位置,当然也可能会出现到了下标为9+16=25的位置

总结:
在1.7的HashMap中我们put存数据过程如下
① 判断HashMap的数组是否为空或者长度是否为0,如果为0,初始化HashMap,然后计算出key的hash值,
② 通过hash值计算出数组下标,在对应数组下标的位置去添加链表节点
③ 如果数组不为空并且长度不为0,我们通过下标找到数组对应的位置,遍历链表,如果key和hash都相等则替换value值,如果不相等则插入(头插)元素;

get取数据如下
获取key的hash值,获得下标,然后取出数据即可

1.8的HashMap中加入了红黑树

为什么要加入红黑树呢?
因为在1.7中,就算我们在怎么去扩容之类的,每个下标上链表的长度都会不断的增长,这会让我们的查询效率下降,所以在1.8中我们加入了红黑树,为什么不适用其他的结果呢?如二叉树之类的,因为红黑树的查询和插入的速度都很均匀,不想链表插入很快,查询很慢;不像二叉树,查询很快,插入很慢,综合来讲我们使用红黑树。

在1.8HashMap的源码中我们多了几个常量,树化的数量默认为8,链表化的数量默认为6,就是说当链表的节点长度大于8时,链表结构会转为红黑树结果,当红黑树的节点小于6时,会退化成链表,那么当链表节点大于8时一定会转为红黑树吗,也不一定,我们还需要去判断数组的长度是否大于64,为什么呢?因为在1.7中,我们通过扩容的方式确实可以解决链表长度的问题,所以1.8中进行沿用,当数组的空间达到一定程度时,我们则需要将其转换为红黑树了

在1.8的put方法相对于1.7的put方法在源码中多了对于链表节点数的判断,不同的是在1.7中我们把数据添加到了链表的头部(头插法),而在1.8中我们是直接在尾部进行添加的,为什么呢?因为如果对应下标的地方有链表节点的话,我们一定会遍历链表,获取节点个数,判断是否需要转化为红黑树,所以在遍历的过程中,就可以判断新增元素在节点中是否存在,如果不存在,就直接在尾部添加节点了。

1.8 中初始化方法和扩容方法是写在一个方法内部的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值