【HashMap】HashMap底层数据结构

  • Post author:
  • Post category:其他



10分钟学会HashMap底层视频分析

<点击>

HashMap:散列表集合,实现了Map接口,Map又实现了Iterator接口。遍历Map可以用Iteratoer实现,也可以用Entry(HashMap内部类)实现

两种实现方式:

while(iterator.hasNext)

for(map.Entry entry : map.getEntrySet())


数据结构:数组+链表

数组:存储区间是连续的,占用内存大,存慢,取值快;

链表的存储区间离散,占用内存宽松,增值快,取值慢;

两者结合起来,就实现了HashMap:存、取都很快。


那么,两者具体是怎么结合的呢?

HashMap里有一个数组Node<K,V>[]默认16个,存储的K、V、hash、next(Node)。(Node<K,V>实现了Entry<K,V>接口,它其实就是一个Entry)

put(K,V)——>根据K算出下标i,键值对存在i处,newNode(hash,key,value,next)形成一条数据链,

get(K)——>getNode(hash,key),根据key算出下标i,取出i位置的Node<K,V>,比较hash,如果相同就直接返回,如果不同继续next,直到没有next了为止。

<数组默认16个>

(0) Entry<K,V> —put的数据—put的数据  ——>代表数组下标i=0处,存的数据(键值对)

(1) Entry<K,V> —put的数据—put的数据  ——>代表数组下标i=1处,存的数据(键值对)



(15)………………………………………………….——>代表数组下标i=15处,存的数据(键值对)


Node<K,V>位置i:key的哈希值,对(数组长度-1)取模,(len-1) & hash相当于取模,这里暂且将取模认为是取余,下面好理解

i:0、1、2…15

key的哈希值:3、18;1、16;

确定i位置:3、18对15取余,键值对就存在i=3后面;1、16对15取余,键值对就存在i=1后面

取模:5 mod -3 = -1,结果的+-取决于-3;让结果尽可能小(因为商的值向负无穷舍弃小数位)<=取余结果

取余:5 % -3 = 2,结果的+-取决于5;让结果尽可能大(因为商的值向0方向舍弃小数位)

拿取余作为例子:5/3 =1.6666(不舍弃小数位的话),3-1.66666<2;由于商的值向0方向舍弃小数位,所以3-1=2


据上所述,每个数组元素后边都跟了一个链条,这就存在取值效率问题了,红黑树很好的解决了这个问题(TreeNode<K,V> 也实现了Entry接口,和Node不同的是,多了left、right等属性,用于交换位置,提高取值效率,如下)。

8        8

7        7

6        6

5        4 5

4



版权声明:本文为qq_29266921原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。