HashMap源码分析(通俗易懂)(JDK17)

一、HashMap 概述

在 Java 中,HashMap 是一个非常常用的 Map 接口的实现类,它基于哈希表(数组 + 链表/红黑树)实现键值对存储,提供 O(1) 时间复杂度的查找、插入、删除操作。

本文将基于 JDK 17 源码,详细分析 HashMap 的内部结构、关键方法以及扩容机制。

二、HashMap 数据结构

在 JDK 17 中,HashMap 的核心数据结构是一个 Node<K,V>[] 类型的数组。每个节点(Node)保存一个键值对,并且包含一个指向下一个节点的引用(在哈希冲突时,形成链表)。

transient Node<K,V>[] table;

2.1 Node 类

NodeHashMap 内部存储的基本单元,表示一个键值对。每个 Node 包括键、值、哈希值和指向下一个节点的指针:

static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

2.2 HashMap 数组和链表

HashMap 使用一个数组来存储键值对,每个数组元素可能是一个链表的头节点。在哈希冲突时,多个键值对会被链式存储在同一个数组位置。自 JDK 1.8 以来,当链表长度超过一定阈值(默认为 8),链表会被转化为红黑树,优化查找效率。

2.3 红黑树

在 JDK 17 中,如果哈希冲突导致某一槽位的链表长度超过 8,链表会转化为红黑树。红黑树的引入有效提升了高哈希冲突情况下的查询性能,最坏情况下的查找时间复杂度由链表的 O(n) 降低到了 O(log n)

三、HashMap 关键方法分析

3.1 构造 方法

  
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY(最大容量))
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        //tableSizeFor方法会返回找到大于或等于 initialCapacity 的最小2的幂
        //也就是数组长度始终为2^n
        this.threshold = tableSizeFor(initialCapacity); 
    }
 
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR); //调的双参的构造方法
    }

  
    public HashMap() {
    //此时不会显示初始化,在put第一个元素的时候才会初始化
        this.loadFactor = DEFAULT_LOAD_FACTOR; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值