利用数组+链表的方式实现HashMap的一些功能

目录

1、HashMap解决了什么问题?

 2、怎么实现呢?

什么是hashcode:

hashcode特点:

初始容量大小和加载因子:

3、具体代码演示


1、HashMap解决了什么问题?

HashMap底层使用数组加(jdk1.7以前)链表(jdk1.8以后在链表节点不小于8的时候会调整为红黑树)的结构完美的解决了数组和链表的问题,
使得查询和插入,删除的效率都很高,每个元素节点都有一个next属性指向下一个节点
,这里由数组结构变成了数组+链表结构(图是别人的)

 

HashMap特点:

它是查询效率最高的数据结构,因为它是通过计算散列码来决定存储位置的,无论数据有多大,它的查询速度都是固定的。

 2、怎么实现呢?

计算出键的hashcode,该值用来定位要将这个元素存放到数组中的什么位置,如果数组这个位置索引的地方是空的,直接将元素放进去就好了。如果已经有元素占据了索引该位置,需要使equals比较该位置的key和当前key是否相等。相等就覆盖,不相等就往链表后面加数据。

什么是hashcode:

在Object类中有一个方法:public native int hashCode();调用这个方法会生成一个int型的整数,我们叫它哈希码,哈希码和调用它的对象地址和内容有关

hashcode特点:

对于同一个对象如果没有被修改(使用equals比较返回true)那么无论何时它的hashcode值都是相同的,对于两个对象如果他们的equals返回true,那么他们的hashcode值也相等

根据hashcode的特点,用key的hashcode % 数组初始容量,在数组上确定唯一位置

初始容量大小和加载因子

初始容量大小是创建时给数组分配的容量大小,默认值为16,加载因子默认0.75f,用数组容量大小乘以加载因子得到一个值,一旦数组中存储的元素个数超过该值就会调用rehash方法将数组容量增加到原来的两倍,专业术语叫做扩容。在做扩容的时候会生成一个新的数组,原来的所有数据要重新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能。

3、具体代码演示

 定义一个Node节点类

import java.util.Map;

public class Node<K, V> implements Map.Entry<K, V> {
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HashMap底层使用数组+链表/红黑树的数据结构实现,最重要的是利用了哈希算法来快速定位数组中的元素。 具体的实现过程如下: 1. 初始化时创建一个Entry类型的数组table,每一个Entry对象都包含key、value和一个指向下一个Entry对象的指针next。 2. 当向HashMap中添加一个键值对时,首先根据key的哈希值和数组长度计算出该键值对在数组中的位置(即下标),如果该下标位置没有元素,则直接将该键值对作为一个新的Entry对象插入该位置。 3. 如果该下标位置已经存在元素,那么就需要遍历该位置的所有元素,找到与新键值对key相同的元素,然后将新的value替换旧的value。如果没有找到相同的key,则将新的键值对作为一个新的Entry对象插入该位置,并将其指向原有元素的next。 4. 当遍历链表的元素达到一定数量时,为了提高性能,会将链表转化为红黑树,这样查找、插入、删除等操作的时间复杂度从O(n)变为O(logn)。 5. 当数组长度达到一定程度时,需要对数组进行扩容,扩容的大小一般为原来的两倍,同时需要将所有元素重新计算hash值并重新插入到新的数组中。 6. 当从HashMap中删除一个键值对时,首先根据key的哈希值和数组长度计算出该键值对在数组中的位置,然后在该位置的链表/红黑树中查找是否存在该key,如果存在则删除对应的Entry对象,如果不存在则不做任何操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值