基础面试题—— HashMap的数据结构和它的工作原理

HashMap 的数据结构是由数组、链表和红黑树组成的混合结构

HashMap 内部维护了一个数组,称为桶数组(bucket array)。每个数组元素称为一个桶(bucket),每个桶存放的是链表或红黑树的头结点。
每个键值对都会通过键的哈希值(hash code)映射到这个数组中的一个桶内。这个过程通过计算 hash(key) 来确定具体的数组索引。

当多个键通过哈希函数映射到同一个桶时(即发生哈希碰撞),这些键值对将会被存储在该桶对应的链表中。

为了提高在大量哈希碰撞情况下的查找效率,当链表的长度超过一定阈值(默认为 8)时,链表会自动转换为红黑树。红黑树是一种自平衡的二叉搜索树,可以在 O(log n) 时间内完成查找、插入和删除操作。
当红黑树中的节点数量减少到一定程度(默认为 6),红黑树又会转换回链表,以节省内存。

HashMap 的工作原理

存储元素
当向 HashMap 添加元素时,会首先计算键的哈希值。这个哈希值再经过一次进一步的位运算(通常是 hashCode 的高位和低位混合,以减少哈希碰撞),最终决定该键值对存放到哪个桶中。
处理哈希碰撞: 如果两个键的哈希值映射到了同一个桶中,则会在该桶中的链表(或红黑树)中按顺序插入新的键值对。

查找元素
根据键的哈希值计算出所在的桶的位置,然后在桶中的链表或红黑树中查找具体的键值对。

扩容
当 HashMap 中的元素数量超过一定的比例(称为负载因子,默认是 0.75),HashMap 会进行扩容操作。扩容时,HashMap 将桶数组的大小增加为原来的两倍,并重新计算所有键的哈希值,以决定它们在新的桶数组中的位置

HashMap 重要特性
无序:HashMap 不保证键值对的顺序。
允许 null:HashMap 允许一个 null 键和多个 null 值。
线程不安全:HashMap 是非线程安全的,多线程情况下建议使用 ConcurrentHashMap

当在 HashMap 中插入相同的键(key)但不同的值(value)时,HashMap 底层会进行以下处理?

先通过哈希函数计算出该键值对应该存放在哪个桶(bucket)中,如果该桶为空,直接在该位置创建一个新的节点存放键值对。如果该桶不为空,说明存在哈希碰撞,HashMap 会遍历桶中的链表或红黑树来寻找该 key 是否已经存在,在遍历桶中的链表或红黑树时,HashMap 使用 key 的 equals() 方法来判断是否存在相同的 key,如果找到相同的 key,则认为这是一个更新操作。HashMap 会将该 key 对应的 value 更新为新的值。如果没有找到相同的 key,说明这是一个新的键值对,HashMap 会将其插入到桶中的链表或红黑树中,插入完成后,HashMap 会检查是否需要扩容(如果当前大小超过了负载因子的阈值),并在必要时执行扩容操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值