HashMap的底层数据结构及原理

HashMap的主干是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value键值对。

HashMap是基于hashing的原理 ,我们使 用put(key, value)存储对象到HashMap中,使用get(key)从HashMap中获取对 象。 当我们给put()方法传递键和值时,我们先对键调用hashCode()方法,返回 的hashCode用于找到bucket位置来储存Entry对象。 ”这里关键点在于指出, HashMap是在bucket中储存键对象和值对象,作为Map.Entry。

HashMap数据结构图如下:

 在jdk1.7之前是数组+链表的形式,并通过entry节点保存key和value值;当Hash冲突比较严重的时候,在数组上形成的链表就会变的越来越长,由于链表是不支持索引查询的,所以这个时候要想在链表中找一个元素的话就需要遍历一遍链表,最坏的结果是查找的元素在链表的末尾,这样显然会导致查询效率大大降低;

        所以为避免这一问题的发生,在jdk1.8加入了红黑树,红黑树是一个自平衡的二叉查找树,使用红黑结点并使得两端保持相对平衡;所以jdk1.8后HashMap的底层数据结构是数组+链表+红黑树的形式。

        Jdk8开始当链表高度到8、数组长度超过64时,会将链表转为红黑树,元素以内部类使用Node类存储Key和Value。

        通过计算key的hash值,进行二次hash然后对数组长度进行取模,获得对应数组下标; 获得下标后,会先判断下标位置是否存在元素,如果下标位置没有元素,则直接创建Node存入数组;如果存在元素就会产生hash冲突

        冲突产生后,先对key值进行equals()比较,如果key值相同则取代该元素,不同则通过尾插法插入链表,在插入的同时遍历链表计算高度,如果中途存在key值相同的元素则进行覆盖;如果没有就直接插入到链表尾部。

        插入完成,对链表高度进行判断,如果链表高度达到8,并且数组长度到64则转变为红黑树;反之,如果红黑树结点低于等于6则会退化为链表。

        注意,如果Key为null的话,则存在下标0的位置上
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值