核心数据结构-HashMap

Map是非常常用的一种数据结构,在java中提供了成熟的Map实现,最常用的Map实现如下图所示:

核心数据结构-HashMap

 从图中可以看出,围绕着Map接口。最主要的实现类有Hashtable、HashMap、LinkedHashMap、和TreeMap,在Hashtable中海油配Properties类的实现。

首先值得关注是HashMap和Hashtable两套不同的实现,两者都实现了Map接口,从表面上看他们并没有多少差别,但其内部实现上却有着诸多微小差异。

首先Hashtable的大部分方法做了同步,而HashMap没有,因此HashMap不是现成安全的,其次,Hashtable不允许key或者value使用null值,而HashMap可以,第三内部算法上,他们对key的hash算法和hash值到内存索引的映射方式不同。

HashMap实现原理:

HashMap就是将key做Hash算法,然后将hash值映射到内存地址,直接去的key所对应的数据,在HashMap中,底层数据结构使用的是数组,所谓的内存地址即数组的下标索引。

什么是hash冲突?

 核心数据结构-HashMap

 由上图所示,需要存放到HashMap中的两个元素1和2,通过hash计算后,发现对应在内存中的同一个地址,这时就出现了hash冲突。

hash冲突的解决方式:

虽然HashMap的底层实现使用的是数组,但是数组内的元素并不是简单的值,而是一个Entry类的对象,因此,HashMap实现结构如下所示:

核心数据结构-HashMap

 可以看到HashMap的内部维护这一个Entry数组,每一个Entry表项包括key、value、next、hash几项。这里要特别注意其中的next部分,它指向了另外一个Entry。进一步阅读HashMap的put()源码,可以看到当put操作有冲突时,新的Entry依然会被安放在对应的索引下标内,并替换原有的值,同时,为了保证旧值不丢失,会将新的Entry的next指向旧值,这便实现了一个数组索引空间内存放多个值项。因此,HashMap实际上是一个链表的数组。