JDK1.7中HashMap底层存储原理

底层存储结构

       我们首先来探讨一下HashMap的存储结构,相信很多人都听过,在JDK1.7中是以数组+链表的形式存储的(JDK1.8为数组+链表+红黑树来存储的,因为学得不好就先从JDK1.7简单的入手哈哈哈)。数组+链表的形式,可以先在脑海中形成这样一个印象,emmm大概就是这样的吧。

JDK1.7中HashMap底层存储原理_第1张图片

       基本存储结构是有了,那HashMap到底是怎么存储的嘞?我们先举一个例子:

       假如我是一名老师(自己都在心里感叹可别误人子弟了),在开学第一天我要给我们班级的同学们分座位。我大致的扫了一眼班级里的座位,大概是16个,嗯嗯记下了。这时候小A背着书包在门口敲门,因为当时在忙着写博客嘛,我就没抬头问了一声:“是谁在门口伫立?”小A回答:“是小A”。因为是新开学嘛,我也不认识小A,我就拿着班级名册去找,啊原来是编号为0001的小啊,现在问题来了该让他坐在那里嘞?我掐指一算,就做班级门口吧,风挺大的啊哈哈。就这样我给小B、小C、小D、小E以此安排了座位,都给我挨着门口坐hhh。现在的座位图应该是这样

JDK1.7中HashMap底层存储原理_第2张图片

       这时候小F来了,我看着编号为0006的小F,低头掐指一算,坐门口第一个。小F就说了:“老师你让我坐门口吹风我也不说啥了,但这位置小A坐着了,我也不能坐他身上啊?”。我一想也对哦,那你就坐小A旁边吧,这样小F也入座位了。在这之后小G、小H、小I也就坐了。现在的座位图应该是这样

JDK1.7中HashMap底层存储原理_第3张图片

       现在所有同学座位分配完毕。仔细回忆这个流程:

       因为HashMap存储的是Key-Value,所以上述例子每一个同学代表着一个元素,同学的名字就是Key,书包就是Value。因为每个同学都有自己的书包,所以书包要和自己待在一起。小A刚来,因为我不认识小A,所以我找寻了班级名册确认了小A的编号,这个过程相当于用每个元素中的Key调用了HashCode方法。HashCode方法可以这样理解:它的返回值就是根据对象的内存地址换算出的一个值。知道小A的编号后,我做了一个掐指一算的过程,这个掐指一算的过程就相当于调用了Hash函数(又叫散列函数)是把任意长度的输入通过散列算法变换成固定长度的输出。靠墙一排的座位代表着HashMap底层存储的数组结构,也就是我们总能听到的哈希表(又叫散列表)。当小F来的时候,我掐指一算也让他坐了小A的座位,这种情况叫做哈希冲突(又叫哈希碰撞)。为了让小F也能有座位坐下,我让他坐在了小A的旁边,这就是一种解决哈希冲突的方式,拉链法(其他解决冲突方式改天回去好好复习再发)。至此HashMap存储的小例子就说完了。说了这么多,大家可能对HashMap底层存储在脑海中有了一些了解,下面我们一起来探讨下数组里面究竟存储的是什么?

       通过上面的例子我们可能知道了,座位上放的不就是人和书包(Key-Value)么?既然可以存在链表,那一定还有一个指针咯(感觉C里面的指针比较适合解释这个概念)?既然是往数组里面存,是不是有一个可以存放上述元素的容器呢?一起看下源码

    static class Entry implements Map.Entry {
        final K key;
        V value;
        Entry next;
        int hash;

        Entry(int h, K k, V v, Entry n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }
    }

上图为HashMap的基本存储单位-内部类Entry,由图可以得知Entry类有四个属性,分别是hash、key、value、next。

hash:存放的为当前Entry对象的hash值(关于hash值、hash函数、hashCode函数的区别下章再总结)

key:存入数据的键值

value:存入数据的value值

next:存入的是下一节点的地址

知道了hashMap存储的基本单位后,让我们来看下table数组的源码

transient Entry[] table = (Entry[]) EMPTY_TABLE;

       table数组即为哈希表,调用构造器创建HashMap之后,哈希表(数组)是一个空表,只有当真正存放元素时,才会创建Entry[]。到这里HashMap的底层存储原理大家应该就清晰了,大致是这个样子。

JDK1.7中HashMap底层存储原理_第4张图片

       最后把HashMap的概念整理下,在JDK1.7中HashMap是以哈希表(table[])和哈希桶bucket(实际上是一个由Entry组成的链表,新加入的Entry放在链头,最先加入的放在链尾)构成底层存储结构。

       程序员新人小白,如有错误之处还望提出,必细心改正。

 

你可能感兴趣的:(Java集合)