面试准备一之HashMap

看了很多面经都讲了HashMap 今天自己也来讲一讲

在JDK1.8之前 HashMap还是很本分的坚持着数组+链表的结构,然并卵 好景不长,JDK1.8后如果链表中的数据超过8个,则会插入到红黑树种来存取(个人感觉,因为读取速度肯定是红黑树大于链表的。当数据量过大或存在大量的冲突时链表的查找速度较慢所以应用红黑树的结构来解决问题)。接下来,就带着大家讲讲HashMap 的前世和今生吧。

 

首先,我们来讲一讲JDK1.8之前的HashMap,数组+链表结构,为什么要采用这种形式呢?因为传统的链表添加删除操作快,但读取速度慢,而数组读取速度快,但添加和删除的速度慢(具体可见数据结构哈),而采用数组加链表的方式就极大程度的改进了读取和增删的速度,HashMap具体结构如下图所示。

很容易我们可以看到HashMap是由一组Entry数组和链表来组成的,而对应的<K,V>是如何插入的呢?那就要说说我们大名鼎鼎的hash()函数了,放一下源码吧,待我找找哈。。。。

public class HashMap<K,V> extends AbstractMap<K,V>(实现克隆和序列化以及继承AbstractMap我就先略过哈)
    implements Map<K,V>, Cloneable, Serializable {

可以看到HashMap中的hash key value next,hash个人认为是存储位置(没记错HashMap的大小是65536也就是int的大小了哈),key value不必多说,这个next应该就对应了链表了,当然存的时候没有hash冲突就放到链表首位了哈。咱们接着放源码

看这风骚的hashCode函数,就知道hash()函数存在其中,不过竟然是用key和value来计算得到的存储在entry数组中的位置吗?return中间那个是^记得没错是异或吧...,查了一下 果真没错,来我们继续点开这个Object的函数

上面的就不翻译了,看到了吧 Object里hashCode这个如果是null的话返回时啥> 0! 终于知道为什么HashMap会允许null建了吧,哈哈!而且key值为null的value可是存在了entry数组的打头哦!这还不够,为了详细了解hashCode函数我又鬼使神差的点了进去,然后,和自己的无符号右移16为的数做异或,估计这回返回的数组位置就可以不重复啦,当然Object里面也有对应的注释,如下:

上面就说明了,对一个固定了object,只有一个integer的数值对应,那么对于hash函数有几种呢,本宝宝找到了一下三种

操.....太卡了  具体的先留着 以后分析行么各位亲?咱接着往下走

然后就是咱们的存值操作,其实也就是putVal了,来上源码~

狗在这先,未完待续啊