HashMap如何在Java内部运行


在本文中,我们将了解HashMap在JAVA中的内部工作方式。另外,我们将看看Java 8对Hashmap的内部工作进行了哪些更改以使其更快。

甲HashMap的是用于键值对存储的映射的图。要了解有关HashMap的更多信息,请访问本文:Java HashMap。

Java中的HashMap遵循哈希原理。这是一个数据结构,允许我们存储对象并在已知密钥的情况下以恒定时间O(1)对其进行检索。在哈希中,哈希函数用于链接HashMap中的键和值。

Hashmap如何计算Java中存储桶的索引 要了解HashMap在Java内部的工作方式,我们必须了解HashMap如何计算存储桶的索引。到目前为止,我们知道HashMap的内部结构,即HashMap维护存储桶的数组。但是,当我们存储或检索任何键值对时,HashMap会为每个操作计算存储区的索引。Key对象用于计算存储桶的索引。通过使用此键,使用hash(key)HashMap的private方法计算哈希值 。

注意: hash(key)该方法是HashMap的私有方法,它返回键的哈希值,如果哈希值太大,则将其转换为较小的哈希值。

但是会发生什么,如果Key Object的哈希值返回的整数大于数组的大小,即hash(key)> n,则 ArrayOutOfBoundsException可能会引发这种情况。为了处理这种情况,HashMap使用表达式将散列值减小为0到n-1之间:

索引计算表达式:

index = hash(key) & (n-1)

现在,生成的索引值由HashMap用于查找存储区位置,并且永远不会生成任何异常,因为索引值始终从0到n-1。

用什么put()方法

让我们记下hashmap中put方法的内部工作。

首先,检查密钥对象是否为空。

如果键为null,则将值存储在位置中,因为null的哈希码始终为0。 table[0]

然后,在下一步中,通过调用键的哈希码,使用键的哈希码计算哈希值hashCode() 。此哈希值用于计算数组中用于存储Entry对象的索引。JDK设计人员很好地假设可能有一些编写不佳的 hashCode()函数可以返回非常高或很低的hash值。为了解决此问题,他们引入了另一个hash()函数,并将对象的哈希码传递给此hash()函数,以使hash值处于数组索引大小的范围内。

现在indexFor(hash, table.length)·调用该函数以计算用于存储Entry对象的确切索引位置。

如何解决冲突

这是主要部分。现在,我们知道两个不相等的对象可以具有相同的哈希码值,如何将两个不同的对象存储在称为存储桶的相同数组位置中。

答案是LinkedList。如果您还记得的话,Entry类具有属性“” next。此属性始终指向链中的下一个对象。这正是LinkedList的行为。

因此,在发生冲突的情况下,Entry对象以链接列表的形式存储。当Entry对象需要存储在特定索引中时,HashMap会检查是否已经存在一个条目。如果尚无条目,则将条目对象存储在此位置。

如果已经有一个对象坐在计算索引上,则检查其下一个属性。如果为null,则当前条目对象成为LinkedList中的下一个节点。如果下一个变量不为null,则继续执行该过程,直到下一个变量被评估为null。

如果我们添加另一个具有与之前输入相同的键的值对象,该怎么办?从逻辑上讲,它应该替换旧值。怎么做的?好了,在确定Entry对象的索引位置之后,在对计算出的索引上的LinkedListd进行迭代的同时,HashMap为每个入口对象在键对象上调用equals方法。

LinkedList中的所有这些条目对象都将具有相似的哈希码,但是 equals() 方法将测试真实相等性。如果key.equals(k)为true,则两个键都被视为相同的键对象。这将导致仅替换输入对象内的值对象。


原文链接:http://codingdict.com