Java集合之HashMap

回顾

在上一篇 Java 集合之LinkedList 我们讲了Collection的一个实现类LinkedList,是基于链表的实现,按原来打算是准备介绍HashSet,但是HashSet又与HashMap关系密切,所以这次还是先介绍HashMap吧

首先需要注意的是HashMap不是Collection的实现 而是Map的实现,看下Map结构图

父接口Map是用来存储具有映射关系的数据:Key-value

Map中的key和value都可以是任何引用类型的数据

常用String类作为Map的“键”

key和value之间存在单向一对一的关系,即通过指定的key总能找到唯一的 确定的value

照例我们看看Map接口中声明的方法

对应Collection

我们看到Map中并没有add addAll 方法 却有了put putAll方法 put系列方法就代表了新增和修改的方法

我们在看看HashMap实现类中有哪些方法

HashMap除了实现了Map的一般方法还多了许多方法 多是服务于具体实现的

HaspMap实现较为复杂,若一行行看源码,肯定比较吃力 ,我们先从思想上把握它

原理

1.HaspMap是什么?

HashMap是为了存储kay-value键值结构而服务的,我们假想一个例子

考试的教室有100个座位, 那怎么让同学们对号入座且尽量分散呢(避免提前商量抄袭),
我们先把座位进行编号。比如1到100 ,然后根据同学的特征信息(比如学号)计算出一个值 刚好一一对应到我们的编号1到100,
同学们无法知道这个计算的方法,那么同学们就会尽量分散 从而无法提前商量了。
复制代码

2.HashMap的实现原理是什么呢?

put方法

在上面我们知道座位的编号相当于key,而每一个同学就是一个value,同学们入座完毕后,那么这个key-value就完成了, 通过代码我们知道 座位是用数组来实现的

数组初始化时每个单元都是null, 当第一个同学A来了,我们根据一个hash算法得出他的座位

index=Hash("A的学号")
复制代码

此时得出index=2 即应该在2号座位入座

把每个同学看作是一个Entry,就这样 同学们相安无事的陆续就坐了。

慢着我们仿佛发现了问题,这个问题就在与这个Hash方法 这个hash方法怎么实现呢?与他相关的参数只有同学么?

当然不是,万一教室不是只有100个座位 而是有200个座位呢 那原来的计算方法就不管用了。 所以我们知道了 这个hash方法应该是这样的

index=Hash(length,"A的学号")//length相当于座位数
复制代码

我们看另一个问题 当数据越来越多,万一根据hash算法得出的index是一样的怎么办?总不能把原来的entry移除吧

答案是这里每个Entry又是一个链表(可参见Java集合之LinkedList),若遇到重复的则把新来的放到链表的头部

上图entry1原本在index=2的位置 当entry6来了时 把entry6放到了链表的头部 entry1放到链表的尾部 entry6的next指向entry1,这种叫做头插法,即每次新元素来时插入头部。

可以理解为了原来座位有人了,新来的我搬个凳子过来和你用一个桌子,哈哈

这样就完成了座位了分配且又根本的解决了座位重合的问题

get方法

就这样每个同学都陆续就坐完毕,但是老师点名找“A”时,怎么找呢,这就是查找方法get

最简单的是根据hash方法算一遍

index=Hash(length,"A的学号")//length相当于座位数
复制代码

得到index=2,但是这时根据学号算出的index=2的位置有两人,这怎么办?

也简单 挨个遍历一遍 核对下具体学号就完事了。

总结

hashMap是基于数组加链表的实现

这里的hash算法是整个实现的核心,篇幅原因暂且不表,待后续文章放出

链表头部插入的优势在于:后加入的元素被查找的可能性更大,那么遍历链表时,查到的速度最快,性能损耗最少

还有个问题是 我们看到数组长度 是随着越来越大的 那么动态扩容成了问题之重

喜欢本文的朋友们,欢迎长按下图关注订阅号我的编程笔记,收看更多精彩内容

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值