HashMap、ArrayList实现原理和扩容机制(面试必问)

本文探讨了HashMap的实现原理,包括使用哈希算法计算hash值存储数据,以及解决哈希冲突时采用的链表和红黑树策略。在HashMap扩容方面,当负载因子超过0.75时,会进行扩容,将键值对重新分布。ArrayList的扩容则是在元素数量达到数组容量的1.5倍时,创建新的1.5倍容量数组并复制旧数据。相比之下,LinkedList作为双向链表,没有固定初始化大小,增删速度快但查询慢。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hashmap是用hash算法实现的,我们通过put一个key和value进行存储,用get(key)来获取,在传入key时,hashmap会根据key.hashCode()计算出hash值存储到bucket里面,当发生hash值相同,也就是hash冲突时,会使用链表+红黑树存储相同的hash值的value,如果冲突少,就用链表,冲突多,就用红黑树

Hashmap扩容:

·HashMap 初始化大小是 16 ,扩容因子默认0.75(可以指定初始化大小,和扩容因子)
·存的对象*负载因子*0.75(默认)大于总量就要扩容,扩容是键值重新排布,重新对底层数组容量取余分布
·JDK1.8之前是数组+链表结构、JDK1.8及之后是数组+链表+红黑树
·HashMap集合可以存储null键和null值

### Java 中 ArrayList 的默认容量、扩容机制及负载因子 #### 默认容量 在 Java 中,`ArrayList` 是一种基于动态数组的数据结构,默认情况下,当创建一个 `ArrayList` 实例而未指定初始容量时,其默认容量为 **10**。这意味着底层的数组会初始化为大小为 10 的空间来存储元素[^1]。 ```java public ArrayList() { this.elementData = new Object[10]; } ``` #### 扩容机制 `ArrayList` 的扩容机制并不依赖于加载因子的概念,而是通过简单的逻辑判断当前数组的实际大小是否超出了现有容量。一旦尝试向 `ArrayList` 添加新元素而导致所需最小容量超过当前容量时,便会触发扩容操作[^4]。 具体来说,扩容过程由内部方法 `grow(int minCapacity)` 来完成。该方法的主要作用是计算新的容量并分配更大的内存区域给底层数组。通常情况下,新的容量会被设置为原容量的 **1.5 倍**加上额外的空间以确保足够的增长余地: \[ \text{newCapacity} = (\text{oldCapacity} \times 3)/2 + 1 \] 这种策略可以有效减少频繁的小规模扩容带来的性能开销[^2]。 以下是简化版的扩容代码示例: ```java private void grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); } ``` 需要注意的是,在极端情况下(如请求非常大的容量),可能会直接跳过上述公式计算,转而根据需求调整到满足条件的新容量[^3]。 #### 负载因子 与 `HashMap` 不同,`ArrayList` 并不涉及所谓“负载因子”的概念。虽然某些资料可能提到类似术语用于描述其他数据结构的行为模式,但在标准库定义下,`ArrayList` 的扩展行为完全取决于实际使用的元素数目相对于当前可用槽位的比例关系,而不考虑任何预设阈值或比例限制[^5]。 因此总结起来就是: - 默认容量为 10; - 当前容量不足以容纳新增加项时按约 1.5 倍扩大尺寸直至适应为止; - 没有明确意义上的负载因子参与其中控制何时重新组织内部布局等题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值