Hashmap对Java程序员来说并不陌生。除了通常使用开发外,访调员喜欢问很多。Hashmap是哈希表的经典实现。基础数据结构是数组+链接列表。JDK8中还引入了红树和黑树,以解决链接的线性搜索的效率。HashMap非常设计。有超过两千行的源代码。可以讨论很多要点。本文主要分析了Hashmap的次要哈希的目的。
首先,我们必须首先了解哈希代码的角色?哈希图的基础层采用阵列+链接列表/红色和黑树的数据结构来存储键值对的映射关系。阵列是几个哈希插槽溶液。Hashmap将通过密钥计算的哈希代码来计算出价索引。索引确定了键的键。值对应落入。不同的哈希码计算相同的出价索引,这将导致哈希碰撞。一旦发生哈希碰撞,哈希图的搜索效率将从o(1)退化为o(n)或o(logn)。因此,应尽可能散布良好的哈希功能,否则会影响它的效率哈希图。
我们已经知道将根据哈希代码计算哈希图。哈希码的分散化越多,哈希玛普的效率就越高。LET查看首先计算哈希图标签的过程,我们知道为什么必须执行第二个哈希。
以上是基于第二个哈希计算的哈希代码。计算出价的密钥值代码是基础数组的长度。HashMap使用操作代替我们的常见成型操作。在这里,您可以首先跳过。两者的效果是相同的。
如果您不做第二个哈希,让我们看一下任何问题。
当哈希代码为65541时,索引索引结果仍然为5。不同的哈希代码计算相同的竞标和哈希碰撞。
从此过程和操作的过程中,每个人都必须发现,哈希代码的高级别没有参与操作,并且所有这些都被丢弃了。没有任何哈希代码的高级,它不会影响该操作最终索引的计算结果,因为操作中只有低位置。我们认为这种哈希功能不好。它将带来更多的冲突,并影响伸展效率。
如何解决这个问题?最简单的方法是让高位置也参与操作。不同的高点也会导致不同的索引结果,从而降低了哈希碰撞的概率。以下是Hashmap进行第二个哈希的源代码:
Hashmap通过16位和低16位的哈希代码具有新的哈希码,因此也可以参与操作。此函数也称为“干扰函数”。
我们使用相同的哈希代码来查看第二个哈希之后的哈希代码是否会带来不同的效果。仍然假定数组的长度为16,因此,当哈希代码为5时,投标索引为5,而则是结果是相同的。
当哈希代码为65541时,索引结果的设置为4,并且没有哈希碰撞。
可以看出,通过添加干扰函数,哈希图允许两个可能发生冲突并且不再冲突的哈希码。
Hashmap的干扰函数是高度16位和低16位差异或计算,结合了高位置的特征和状态特征,以减少哈希碰撞的概率。为什么16?而不是8或24位或其他位置?
基于计算索引的索引计算的过程,每个人都发现了。位将参与计算;如果阵列的长度为256,则只有8位将参与计算。如果数组的长度为65536,则只有16位将参与计算。HashMap为16位是折叠号。在大多数情况下,哈希图阵列的长度不会超过65536。
Hashmap的底层使用数组+链接列表/红色和黑色树来存储钥匙值对,它将根据键的哈希代码计算哪个密钥值落在数组上。如果不同的哈希代码计算同样的竞标将导致哈希碰撞并影响hashmap的性能。哈希姆普要做的是尽可能避免遇到哈希碰撞,因此添加了干扰功能。干扰功能将区分16位的高度和哈希代码的低点,因此竞标的计算过程也涉及高位置,这将影响最终的招标计算结果并降低哈希碰撞的概率。哪个位将参与竞标的计算取决于哈希图阵列的长度。在大多数情况下,阵列的长度不会超过65536。
原始:https://juejin.cn/post/7100829047042605064