所谓扩容,即当前集合能容纳的数据量达到一个饱和状态 (饱和状态和加载因子有关)之后, 集合需要申请新的存储空间 。
常见的需要扩容的集合 一般是底层基于数组实现 的 ,链表不涉及扩容问题。
加载因子的系数小于等于1,当元素个数超过容量长度*加载因子的系数时,进行扩容。
另外,不同的集合容器,扩容的机制也不同。
一、List接口实现类(ArrayList,Vector)扩容详解
ArrayList:
底层为Object数组
默认容量:0(在jdk1.8以前,ArrayList默认容量是10,从jdk1.8开始,底层Object[] elementData数组初始化为{},并没有创建长度为10的数组,在add元素时才会创建10个容量)
加载因子:1(元素满了才扩展容量)
扩容增量:增量为原容量的0.5倍,新容量为原容量的1.5倍
Vector:
底层为Object数组
默认容量:10(一直没变)
加载因子:1(元素满了才扩容)
扩增容量:增量为原容量的1倍,新容量为原容量的2倍。
二、Set接口实现类(HashSet)扩容详解
HashSet:
底层实现是一个HashMap(数组+链表/红黑树),实现Set接口
默认容量:16(与HashMap相同)
加载因子:0.75(当元素个数超过总容量的0.75倍时,进行扩容)
扩容增量:增量为原容量的1倍,新容量为原容量的2倍。
三、HashMap,HashTable扩容详解
HashMap:
底层实现:数组+链表/红黑树
默认容量:16
加载因子:0.75(当元素个数超过总容量的0.75倍时,进行扩容)
扩容增量:增量为原容量的1倍,新容量为原容量的2倍
HashTable:
底层实现:数组+链表/红黑树
默认容量:11
加载因子:0.75(当元素个数超过总容量的0.75倍时,进行扩容)
扩容增量:增量为原容量的1倍+1,新容量为原容量的2倍+1
最后,有必要说明一下,像LinkedList,TreeSet,TreeMap这类底层数据结构离散(链表,红黑树等)的集合容器,不存在数组的扩容一说,没有初始化大小,也没有扩容的机制,新增元素时会直接为新元素动态分配内存。