📜  Java中HashMap的内部工作(1)

📅  最后修改于: 2023-12-03 15:01:49.743000             🧑  作者: Mango

Java中HashMap的内部工作

简介

HashMap是Java中常用的一种数据结构,它利用哈希表来实现键值对的存储和快速访问。在Java中,HashMap是非常常用的一种集合类,与HashtableConcurrentHashMap具有类似的功能,但是在性能和线程安全方面都有所不同。

下面将从以下几个方面介绍HashMap的内部工作原理:

  1. 哈希表的实现
  2. 键值对的存储方式
  3. 冲突处理
  4. 扩容机制
哈希表的实现

HashMap内部维护了一个数组table,每个数组元素是一个链表的头节点,即Node类型。Node是一个内部类,用于存储键值对,它包含hashkeyvaluenext四个字段。其中,hash字段保存了键的哈希值,keyvalue字段用于存储键值对,next字段则指向下一个节点的引用。

当添加一个键值对时,HashMap会先根据键的哈希值计算出应该放到数组的哪个位置,然后将该键值对添加到对应位置的链表中。

键值对的存储方式

HashMap中,键值对是通过链表来保存的,即每个数组元素保存了一个链表的头节点,各个键值对通过链表的形式连接起来。因此,在HashMap中,同一个链表中的所有键的哈希值是相等的。

冲突处理

由于不同的键可能会有相同的哈希值,因此在添加键值对时,可能会发生冲突。在HashMap中,当发生冲突时,会将新的键值对加入到对应位置的链表的末尾,也就是说,同一个哈希值的键值对会被依次插入链表的尾部。

扩容机制

由于HashMap内部维护的数组是有限的,因此当链表的长度达到一定程度时,会影响到HashMap的性能。为了避免这种情况,HashMap会在链表长度达到一定阈值时进行扩容。扩容会重新计算每个键在新数组中的位置并重新添加。

下面是HashMap扩容的公式:

newCapacity = oldCapacity << 1;

其中,oldCapacity是原数组的长度,newCapacity是新数组的长度。左移一位等价于将原数组的长度乘以2。在扩容过程中,HashMap不仅会重新计算键在新数组中的位置,还会将原有的键值对复制到新数组中。

总结

HashMap是Java中常用的一种集合类,在实现键值对的存储和访问方面具有很高的性能。它采用了哈希表的数据结构,利用数组和链表来保存键值对。当发生键值冲突时,HashMap会将新的键值对加入到对应位置的链表末尾。为了避免链表过长导致性能下降,HashMap在链表长度达到一定值时会进行扩容。