HashMap底层的基本介绍 面试题(面试必问)

HashMap

一、前言
二、JDK1.7 HashMap的实现
三、JDK1.8 HashMap的实现
四、HashMap的存储过程
五、HashMap的扩容
六、哈希碰撞
七、HashMap为什么使用链表?
八、HashMap为什么使用红黑树?

一、前言

为什么需要了解HashMap底层原理呢?
因为面试的时候面试官一般都会问

HashMap在Java开发过程中是一个十分常用的集合类,它是一个以键值对形式存在的集合类

二、JDK1.7 HashMap的实现

JDK1.7 HashMap的实现是 通过数组+链表的形式

三、JDK1.8 HashMap的实现

JDK1.8 HashMap的实现是 通过数组+链表+红黑树的形式

四、HashMap的存储过程

假设有一段数据 key="柳岩" value="18"

假设向哈希表中存储 "柳岩" "18",根据"柳岩"调用String类中重写之后的hashcode方法计算出值,然后结合数组长度采用某种算法计算出向Node数组中存储数据的空间的索引值.

如果计算出的索引空间没有数据,则直接将"柳岩" "18"存储到数组对应的索引中.举例:通过计算得出柳岩的的索引值是3 那么就存放到数组下标3中

假设向哈希表中在存放一组数据"刘德华" "40" 假设刘德华计算出的hashcode方法结合数组长度计算出的索引也是3 ,那么此时数组空间不为null的话,底层就会比较柳岩和刘德华的hash是否一致,如果不一致,则在此空间划出一个链表节点来存储键值对数据"刘德华" "40" 也就是通过(拉链法)来解决这个问题

五、HashMap的扩容

当链表大于8 数组小于64 扩容是原来的两倍 并将原有的数据复制过来 举例 默认数组长度16 乘以加载因子0.75=12 当数组长度大于12扩容两倍

六、哈希碰撞

假设向哈希表存放数据 "柳岩" "20" 那么通过hashcode结合数组长度计算出的柳岩的索引肯定也是3,此时比较后储存的数据柳岩和已经存在的数据的hash值是否相等,如果值相等,此时发生hash碰撞.
那么底层会调用柳岩所属类String中的equals方法比较两个内容是否相等:
 相等:则将后添加的数据的value覆盖之前的value
 不相等:那么继续向下和其他数据的key进行比较,如果都不相等,则划出一个节点储存数据

七、HashMap为什么使用链表?

链表的实现是为了解决hash冲突:

​那么hash冲突是什么?

首先我们要了解hashmap是怎么存值的,hashmap 的key存放地址是通过hashcode方法计算出值,通过值找到相应位置存放,那么就有可能在hashcode方法计算值的时候出现,相同的值,这个时候就会出现hash冲突了,然而链表很好的解决的hash冲突,在相同的地址上开辟一个链表,存放通过hashcode计算出新的相同key值的数据

八、HashMap为什么使用红黑树?

黑树的实现是为了解决链表过长,出现的效率变低
怎么实现红黑树?
当链表的阈值达到8 并且数值大于64 那么链表自动转换成红黑树
为什么要达到阈值8 或者数组64才实现红黑树?
因为数组过小,如果提前实现红黑树反而效率会减低,因为红黑树需要进行左旋,右旋,变色这些操作来保持平衡.数组小于64时不实现红黑树,搜索时间会快一点
但是如果数组大于64 阈值大于8 实现红黑树,效率则会快一点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值