Code前端首页关于Code前端联系我们

什么是 HashMap?看漫画

terry 2年前 (2023-09-27) 阅读数 64 #数据结构与算法

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

众所周知,HashMap是一个用来存储键值对key-Value的集合。每个键值对也称为 Entry。这些键值对(Entry)分散存储在一个数组中,这个数组就是HashMap的主干。

HashMap数组的每个元素的初始值为Null。

HashMap是什么?看漫画吧

对于HashMap来说,我们最常使用这两种方法:Get Insert

1。 Put方法的原理

调用Put方法时会发生什么?

例如,通过调用hashMap.put("apple", 0),插入一个键为"apple"的元素。此时,我们需要使用哈希函数来确定插入位置(索引) Entry:

index = Hash("apple")

假设最终计算出的索引为2,则结果如下:

HashMap是什么?看漫画吧

但是,由于HashMap长度有限,随着插入的Entry越来越多,无论Hash函数多么完善,都不可避免地会出现索引冲突。例如:

HashMap是什么?看漫画吧

这个时候我们该怎么办?为了解决这个问题,我们可以使用链表

HashMap数组的每个元素不仅是一个Entry对象,同时也是一个链表的主节点。每个Entry对象通过另一个指针指向它的下一个Entry节点。当一个新的Entry节点被映射到冲突的数组位置时,将其插入到对应的链表中即可:

HashMap是什么?看漫画吧

需要注意的是,当一个新的Entry节点插入到链表中时,采用“头插入法” “ 用来。为什么不插入链表末尾会在后面解释。

2。 Get 方法的原理

使用 Get 方法根据密钥找到 Value 会发生什么?

首先将输入的key进行哈希映射,得到对应的索引:

index = Hash("apple")

由于刚才提到的哈希冲突,同一个位置可能会匹配多个Entry,必须顺着主节点匹配链表,一一往下查找。假设我们要查找的键是“苹果”:

HashMap是什么?看漫画吧

第一步,我们查看头节点“Entry 6”。键“Entry 6”是“香蕉”,这显然不是我们要查找的结果。

第二步,我们看下一个节点“Entry1”。“Entry1”的键是一个苹果,这正是我们要找的结果。

之所以将Entry6放在根节点,是因为HashMap的发明者认为在之后插入的Entry更有可能被搜索到

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

———————————————

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

前面提到过,Hash函数用于将一个key映射到HashMap数组中对应的位置:

index = Hash(" apple" )

如何实现分布尽可能均匀的哈希函数?我们正在使用键的 HashCode 值进行某种操作。

HashMap是什么?看漫画吧

index = HashCode (Key) % Length ?

HashMap是什么?看漫画吧

如何进行位运算?有如下公式(Length为HashMap的长度):

index = HashCode (Key) & (Length - 1)

下面我们用key值为“book”来演示整个过程: 1。计算该书的hashcode,十进制结果为3029737,二进制结果为101110001110101110 1001。

2。假设HashMap的长度默认为16,则计算Length-1的结果十进制为15,二进制为1111。 ?

可以说,哈希算法得到的索引的最终结果完全取决于key的hashcode值的最后几位。

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

假设HashMap的长度为10,重复操作步骤:

HashMap是什么?看漫画吧

单看这个结果,表面上没有问题。让我们尝试一个新的 HashCode 101110001110101110 1011

HashMap是什么?看漫画吧

让我们尝试另一个 HashCode 10111001110‸1110 尝试:

HashMap是什么?看漫画吧

是的,虽然HashCode是倒数第二个,第三个Bit从0变成了1,但运算的结果始终是1001。也就是说,当HashMap的长度为10时,有些索引结果更容易出现,而有些索引结果永远不会出现(比如0111)!

这显然不符合哈希算法均匀分布的原则。

回顾一下长度16或其他2的幂,Length-1的值是这样的:所有二进制位都为1。此时,索引结果相当于HashCode的最后几位的值。只要输入的HashCode本身是均匀分布的,那么哈希算法的结果就是均匀的。

HashMap是什么?看漫画吧

HashMap是什么?看漫画吧

作者:程序员小辉
链接:https://juejin.im/post/5a215783f265da431d3c7bba
来源:掘金
。商业转载请联系作者获取授权。非商业转载请注明出处。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门