对HashMap的理解

HashMap是一个逻辑结构,其存储结构是一个链表数组。

单元格1 Enry1(k1,v1,next) --> Entry2(k2,v2,next) --> Entry

单元格2 Enry4(k4,v4,next) 

单元格3 Enry1(k5,v5,next) 

单元格4 Enry1(k6,v6,next) 

单元格5 Enry1(k7,v7,next)

我决得这个结构可能从下面这些阶段过渡而来:(估计完全不是这么回事,方便自己理解就可以了)

1. 完全用一个链表实现

 Enry1(k1,v1,next) --> Entry2(k2,v2,next) --> Entry(k3,v3,next) --> 

 put一个k,v时,直接放前面,其他的后移

 get一个k时,遍历整个链表

2. 发展一下,发现链表遍历太慢了,分个组吧

group1:Entry1(k1,v1,next) --> Entry2(k2,v2,next) --> Entry(k3,v3,next) --> 

group2:Entry4(k4,v4,next) --> Entry5(k5,v5,next) --> 

put一个k,v,先将k进行一个运算,得到分组号,然后放到分组内的链表中,直接放前面,其他的后移

get一个k时,先将k进行一个运算,得到分组号,然后遍历分组内的链表,通过分组和k找到对应的节点。

3. 再发展一下,发现分组越散越好,分组号的计算是一个数学运算,非常快,分组散了,每个分组中的链表的长度就更短了,可能直接就是一个,也可能是多个,多个的话遍历也会很快。所以,这个将k运算成分组号的算法好好设计一下。

4. 定稿一下,给这个从k运算得出的分组号起个名字,叫hash值,一个hash值再运算,得出一个数组中一个索引号,可以直接找到数组的单元格。数组的单元格中是一个链表。

极致的分散近似形成一个一维数组,每个数组元素都是一个只有一个节点的链表,这样是速度最快的,这样的情况是追求的,需要一个好的hash算法。

不极致的情况,是存在多个k得到同一个hash值,找到同一个数组元素,将多个值串成一个链表,这样速度会慢一些,这些是不喜欢的,但也是准许和正确的,尽管我们管这种情况称为hash冲突。

put一个k,v,先将k的hashCode进行运算得到hash值,然后将hash值运算得到数组的索引号,找到一个单元格。先判断该单元格中是否包含该k对应的entry,包含则替换entry中的v。不包含则新建一个entry,封装k,v,next指向之前的entry链表中的第一个节点。

get一个k,先将k的hashCode进行运算得到hash值,然后将hash值运算得到数组的索引号,找到一个单元格,遍历单元格中的链表,找到hash,k都和当前k一样的节点,返回v。

猜你喜欢

转载自jshxwork.iteye.com/blog/2213604