杨斌
发布于 2026-04-15 / 5 阅读
0
0

Java中HashMap的原理

一.HashMap的原理

1.HashMap内部结构

HashMap底层就是一个数组,结合链表和红黑树来解决冲突。无论有没有哈希冲突,数组桶里永远只存“指向节点的引用(箭头)”,节点对象本身(包含 key、value、next)存在堆内存中。

// HashMap底层数组
Node<K,V>[] table;

// 假设桶下标 3 只有一个节点
Node<String,Integer> node = new Node<>("苹果", 5, null);
table[3] = node;   // 桶里存这个节点的引用

System.out.println(node.next);  // 输出 null

2.Java 中 HashMap 的链表节点(Node

static class Node<K,V> {
    final int hash;
    final K key;      // 自己的名字(当前节点的标识)
    V value;          // 自己的数据
    Node<K,V> next;   // 这就是“纸条”,写下一个人的名字
}

其中next 就是“下一个节点对象的地址”(在 Java 里叫“对象引用”)。

3.当同一个数组桶里需要使用链表时,JDK 1.7采用头插法,JDK 1.8+采用尾插法。

(1)头插法(JDK 1.7)

原链表:table[3] → 苹果( next → 香蕉( next → null ) )

插入新节点“橙子”:

  • 创建新节点 橙子,它的 next 指向当前头节点 苹果

  • 然后 table[3] = 橙子

  • 结果链表:橙子 → 苹果 → 香蕉 → null

  • 苹果的 next 没有变,仍然指向香蕉。

所以“苹果”的 next 不需要重新赋值。

(2)尾插法(JDK 1.8+)

原链表:table[3] → 苹果( next → 香蕉( next → null ) )

插入新节点“橙子”:

  • 遍历到链表尾部(香蕉节点),发现 香蕉.next == null

  • 创建新节点 橙子橙子.next = null

  • 香蕉.next = 橙子

  • 结果链表:苹果 → 香蕉 → 橙子 → null

  • 尾节点(香蕉)的 next 被重新赋值为橙子
    如果原链表只有一个节点“苹果”(苹果.next == null),那么苹果的 next 会被重新赋值为橙子


评论