java程序讲解_看八年开发Java程序员讲解Java基础知识第一篇,小白秒入门!

3e02d0a67602ba811b6ce0d35b97dd16.png

HashMap作为最常用的一种Map,就放在第一个讲了。

Map是一个较复杂的结构,本身内容不是太难,但是各个实现的思想完全不同,所以可能关于Map的介绍会比较多,源码分析会放在后边,主要是算法分析。

要讲HashMap,首先要对HashMap有个大体上的的认识,那就是HashMap是什么,为什么用HashMap,HashMap有什么优势等等,等对HashMap有个清晰的认识后再去看源码就很简单了。

HashMap是什么?

HashMap是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。迭代 collection 视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大小(键-值映射关系数)成比例。

将上述描述逐一分条,就是下面的内容:

1、HashMap允许null值和null键;

2、此类不保证映射的顺序,也就是HashMap是无序的,但是这个无序可能与很多人的认知是不同的,并不是很多初学者所理解的无序(实际上HashMap在某些时候其实是有序的),后边会详细的讲解;

3、 此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get 和 put)提供稳定的性能。注意,这句话有一点儿很重要,也是一个使用中可能存在的隐患,那就是“此实现假定哈希函数将元素适当地分布在各桶之间”,是假定,而不是肯定,说明还有可能不是适当的分布,而实际上不是适当分布的这种情况是存在的,而且有人会通过构造特殊hash值去做hash碰撞攻击(不过一般不用考虑),具体后续会讲。

4、迭代 collection 视图所需的时间与 HashMap 实例的“容量”(桶的数量)及其大小(键-值映射关系数)成比例。这句话给我们一个提示,如果需要较好的迭代性能,就不要将初始容量设置得太高,至于为什么,后续会给出详细分析。

第一条就不用讲了,首先是第二条,为什么HashMap是无序的?为什么此类不能保证映射的顺序?

这个问题要从HashMap的存储结构来讲,HashMap并不会直接使用用户设置的key作为key,而是会使用用户设置的key的hash值作为实际key,这句可能有些拗口,下面我们以put方法为切入点,从源码分析。

public V put(K key, V value)

put方法的源码如下:e635a62c0e9efe10abc1296f49b45460.png

可以看到put方法调用了hash方法,然后调用了putVal方法,首先看hash方法的源码:75a489ab3bcf1f6fd5a13a70923ff7b2.png

可以看到,hash方法很简单,判断了一下key是否等于null,如果等于null就返回0,否则就返回后边一串,后边的是一个简单的hash算法,有兴趣的同学可以看些注释为什么采用该hash算法,这里不做过多介绍(该hash算法很重要,建议有一定能力的同学一定要看一下为什么选用该hash算法,尝试去验证一下,然后有兴趣的可以自己写一个hash算法比较一下是否比他这个更优——记住,系统的不一定是最优的,只是在大多数情况下是较好的)。

接下来就是putVal了,putVal的源码如下:728b7463dd9503f4cd1f36d6b296b156.png

首先是判断当前的table是不是空或者null,如果是的话调用resize方法(该方法是一个很核心的方法,后边会单独介绍)初始化,然后用将初始化后tab的大小赋值给n,然后下一行就用上了,下面看这一行:5ec9e69f3764ee142374b2104ca0bed4.png

对于一些基础不好的同学,可能这一行看起来就不是那么的容易搞懂了,其核心是在:

i = (n - 1) & hash

这一段,为什么这么写呢?因为hash值有可能是比tab的size大的,而如果不处理的话就有可能数组越界了,所以需要将hash值处理为比size小的数,而该操作就能做到,至于为什么可以自行思考,不难(取模运算也能达到这样的效果,但是位操作比较快)。

然后就是判断,如果为null了后续的操作都很好理解,构建一个新的node然后插入table中,如果不为null操作就会稍微复杂些,会在下一节中讲解。

由于Map的实现都比较复杂,所以打算做成连载的方式给剖析一遍

想更多了解Java更多知识吗?那还不赶紧加入到我们的学习交流群:559081730      每天发放最新的学习视频和资料,免费共享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值