ArrayList、Vector、HashMap、HashSet的默认初始容量、加载因子、扩容增量

本文探讨了Java中几种常用集合容器如ArrayList、Vector、HashSet及HashMap的默认初始容量与扩容策略。具体分析了它们在达到特定条件时如何通过调整容量来优化性能。

这里要讨论这些常用的默认初始容量和扩容的原因是:

当底层实现涉及到扩容时,容器或重新分配一段更大的连续内存(如果是离散分配则不需要重新分配,离散分配都是插入新元素时动态分配内存),要将容器原来的数据全部复制到新的内存上,这无疑使效率大大降低。

加载因子的系数小于等于1,意指  即当 元素个数 超过 容量长度*加载因子的系数 时,进行扩容。

另外,扩容也是有默认的倍数的,不同的容器扩容情况不同。

 

List 元素是有序的、可重复

ArrayList、Vector默认初始容量为10

Vector:线程安全,但速度慢

    底层数据结构是数组结构

    加载因子为1:即当 元素个数 超过 容量长度 时,进行扩容

    扩容增量:原容量的 1倍

      如 Vector的容量为10,一次扩容后是容量为20

ArrayList:线程不安全,查询速度快

    底层数据结构是数组结构

    扩容增量:原容量的 0.5倍+1

      如 ArrayList的容量为10,一次扩容后是容量为16

 

Set(集) 元素无序的、不可重复。

HashSet:线程不安全,存取速度快

     底层实现是一个HashMap(保存数据),实现Set接口

     默认初始容量为16(为何是16,见下方对HashMap的描述)

     加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容

     扩容增量:原容量的 1 倍

      如 HashSet的容量为16,一次扩容后是容量为32

 

Map是一个双列集合

HashMap:默认初始容量为16

     (为何是16:16是2^4,可以提高查询效率,另外,32=16<<1       -->至于详细的原因可另行分析,或分析源代码)

     加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容

     扩容增量:原容量的 1 倍

      如 HashSet的容量为16,一次扩容后是容量为32

<think> 我们正在讨论Java中的HashMapArrayList初始容量扩容因子。 首先,我们来分别讨论这两个类。 1. ArrayList: - 默认初始容量:在Java中,ArrayList默认初始容量是10。 - 扩容因子:当ArrayList需要扩容时,它会增加当前容量的50%。也就是说,新容量 = 当前容量 + 当前容量 / 2(即1.5倍)。 - 扩容时机:当添加元素时,如果当前元素个数已经等于容量(即数组已满),就会触发扩容。 2. HashMap: - 默认初始容量:在Java 8中,HashMap默认初始容量是16。 - 扩容因子加载因子):默认是0.75。这个加载因子是用于决定何时进行扩容的阈值。 - 扩容机制:当HashMap中的元素数量(即键值对数量)超过当前容量乘以加载因子(capacity * load factor)时,就会触发扩容扩容后的容量是原来的2倍(即新容量 = 旧容量 * 2)。 下面我们分别给出示例代码来展示ArrayListHashMap初始化,并演示扩容行为(但请注意,我们不能直接获取内部容量,因此只能通过观察大小变化来推断)。 但是注意:我们通常不会直接访问内部容量,但我们可以通过反射来查看(这里不推荐在生产环境中使用反射)。下面我们通过添加元素直到触发扩容来观察。 不过,这里我们主要关注的是默认值,所以给出初始化代码默认值。 ArrayList示例代码: </think> ### HashMap初始容量扩容因子 在 Java 中,`HashMap` 的默认初始容量是 **16**(即数组的初始大小),默认加载因子扩容因子)是 **0.75**。当元素数量超过 `容量 × 加载因子` 时,触发扩容,新容量为旧容量的 **2 倍**。 ```java import java.util.HashMap; public class HashMapExample { public static void main(String[] args) { // 默认初始容量=16, 加载因子=0.75 HashMap<String, Integer> map = new HashMap<>(); // 添加12个元素(16*0.75=12)时不会扩容 for (int i = 0; i < 12; i++) { map.put("key" + i, i); } System.out.println("Size before resize: " + map.size()); // 输出12 // 添加第13个元素时触发扩容容量从16→32) map.put("key12", 12); System.out.println("Size after resize: " + map.size()); // 输出13 } } ``` #### 关键点解释: 1. **初始容量**:未指定时默认为 `16`(可通过构造函数自定义)。 2. **加载因子 `0.75`**:平衡时间与空间开销的经验值。过高导致哈希冲突增加,过低导致频繁扩容。 3. **扩容规则**:新容量 = 旧容量 × 2,需重新计算所有元素的哈希位置(耗时操作)。 --- ### ArrayList初始容量扩容因子 在 Java 中,`ArrayList` 的默认初始容量是 **10**。当元素数量超过当前容量时,触发扩容,新容量为旧容量的 **1.5 倍**(即 `旧容量 + 旧容量 >> 1`)。 ```java import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { // 默认初始容量=10 ArrayList<Integer> list = new ArrayList<>(); // 添加10个元素(容量=10)不会扩容 for (int i = 0; i < 10; i++) { list.add(i); } System.out.println("Size before resize: " + list.size()); // 输出10 // 添加第11个元素时触发扩容容量从10→15) list.add(11); System.out.println("Size after resize: " + list.size()); // 输出11 } } ``` #### 关键点解释: 1. **初始容量**:未指定时默认为 `10`(可通过构造函数自定义)。 2. **扩容规则**:新容量 = 旧容量 × 1.5(实际计算:`int newCapacity = oldCapacity + (oldCapacity >> 1)`)。 3. **扩容开销**:需复制整个数组到新内存空间,时间复杂度 O(n)。 --- ### 总结对比 | **集合类型** | 默认初始容量 | 扩容因子 | 扩容倍数 | |--------------|----------------|----------|----------| | `HashMap` | 16 | 0.75 | ×2 | | `ArrayList` | 10 | 动态触发 | ×1.5 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值