HashMap(1)

系列文章目录

1、java集合框架-总概
例如:※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※


提示:※※※※※※※※※※※※※※※※※※※

 


前言

提示:文章内容来自黑马程序员视频课程:
学习重点:

    1、HashMap底层结构:数组+链表+红黑树(jdk1.8)

    2、拉链法处理哈希冲突

    3、JDK1.8中对hash算法和寻址算法是如何优化的(面试题1)

    4、HashMap如何扩容


提示:以下是本篇文章正文内容,下面案例可供参考

一、HashMap简介

HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。

​    JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突(两个对象调用的hashCode方法计算的哈希码值一致导致计算的数组索引值相同)而存在的(“拉链法”解决冲突).JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(或者红黑树的边界值,默认为 8)并且当前数组的长度大于64时,此时此索引位置上的所有数据改为使用红黑树存储。

补充:将链表转换成红黑树前会判断,即使阈值大于8,但是数组长度小于64,此时并不会将链表变为红黑树。而是选择进行数组扩容。

这样做的目的是因为数组比较小,尽量避开红黑树结构,这种情况下变为红黑树结构,反而会降低效率,因为红黑树需要进行左旋,右旋,变色这些操作来保持平衡 。同时数组长度小于64时,搜索时间相对要快些。所以综上所述为了提高性能和减少搜索时间,底层在阈值大于8并且数组长度大于64时,链表才转换为红黑树。具体可以参考 `treeifyBin`方法。

当然虽然增了红黑树作为底层数据结构,结构变得复杂了,但是阈值大于8并且数组长度大于64时,链表转换为红黑树时,效率也变的更高效。 

小结:

1.存取无序的

2.键和值位置都可以是null,但是键位置只能是一个null

3.键位置是唯一的,底层的数据结构控制键的

4.jdk1.8前数据结构是:链表 + 数组  jdk1.8之后是 : 链表 + 数组  + 红黑树

5.阈值(边界值) > 8 并且数组长度大于64,才将链表转换为红黑树,变为红黑树的目的是为了高效的查询。


二、HashMap底层数据结构

1.存储过程


2.存储流程图


3、面试题

1.面试题:HashMap中hash函数是怎么实现的?还有哪些hash函数的实现方式?


对于key的hashCode做hash操作,无符号右移16位然后做异或运算。
还有平方取中法,伪随机数法和取余数法。这三种效率都比较低。而无符号右移16位异或运算效率是最高的。
 

2.面试题:当两个对象的hashCode相等时会怎么样?


会产生哈希碰撞,若key值内容相同则替换旧的value.不然连接到链表后面,链表长度超过阈值8就转换为红黑树存储。
 

3.面试题:何时发生哈希碰撞和什么是哈希碰撞,如何解决哈希碰撞?


只要两个元素的key计算的哈希码值相同就会发生哈希碰撞。jdk8前使用链表解决哈希碰撞。jdk8之后使用链表+红黑树解决哈希碰撞。
 

4.面试题:如果两个键的hashcode相同,如何存储键值对?


hashcode相同,通过equals比较内容是否相同。
相同:则新的value覆盖之前的value
不相同:则将新的键值对添加到哈希表中
 

5.在不断的添加数据的过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来

6.通过上述描述,当位于一个链表中的元素较多,即hash值相等但是内容不相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度(阀值)超过 8 时且当前数组的长度 > 64时,将链表转换为红黑树,这样大大减少了查找时间。jdk8在哈希表中引入红黑树的原因只是为了查找效率更高。

说明:

1.size表示 HashMap中K-V的实时数量 , 注意这个不等于数组的长度 。 

2.threshold( 临界值)  =capacity(容量) * loadFactor( 加载因子 )。这个值是当前已占用数组长度的最大值。size超过这个临界值就重新resize(扩容),扩容后的 HashMap 容量是之前容量的两倍 。

 

附:HashMap源码解析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值