介绍
- 使用动态数组实现
- 默认初始容量10
- 默认扩容为原容量2倍
- 具有fail-fast机制
- 是线程安全的
继承关系 继承类介绍
和ArrayList的继承关系是一致的,就不重复了,没看过ArrayList的可以去看下
变量解析(所有代码都不是完整的源码,而是精简过后的源码!结合源码食用更佳)
//可扩容的动态数组
protected Object[] elementData;
//数组中实际元素的数量 在ArrayList中叫size
protected int elementCount;
//当实际数量超过容量时增加的量 公式是 capacityIncrement + 原容量 = 新容量
protected int capacityIncrement;
//数组最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
源码解析 常用方法解析
add(E e)
作用:将指定元素添加到集合尾部
//同步方法
public synchronized boolean add(E e) {
//结构被修改
modCount++;
//判断是否需要扩容 该方法只在同步函数中调用
ensureCapacityHelper(elementCount + 1);
//赋值后++
elementData[elementCount++] = e;
}
//如果需要扩容 则执行下面的grow方法 假设容量为10 当elementCount为10时将触发grow方法
//获取数组的容量 以下简称旧数组 例子使用默认容量 oldCapacity= 10
int oldCapacity = elementData.length;
//在构建函数中没有指定capacityIncrement 默认值为0 则oldCapacity+oldCapacity = 20
//此时新的容量为20
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//判断最小容量 防止指定初始容量为0
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//判断最大容量 防止溢出
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//新的容量+旧数组 = 新的长度数组
elementData = Arrays.copyOf(elementData, newCapacity);
关于add方法得出结论:
- 如果在构造函数中指定了扩容时增加的量(即capacityIncrement) 那么扩容公式是:
capacityIncrement + 原容量 = 新容量 - 没有指定扩容时增加的量, 默认值为0, 扩容公式是:原容量 + 原容量 = 新容量(即2倍)
remove(int index)
作用:删除指定位置的元素并返回,该位置后续的元素前移一位
//同步方法
public synchronized E remove(int index) {
//结构被修改
modCount++;
//取出旧的value 便于返回给用户
E oldValue = elementData(index);
// 计算出index位置后的所有元素长度
int numMoved = elementCount - index - 1;
//判断是否是数组中最后一位元素 大于0则需要移位
if (numMoved > 0)
//根据index作为长度限制 将index位置后的元素全部前移1位
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work
return oldValue;
set(int index, E element)
作用:用指定的元素替换指定位置的元素
//同步方法
public synchronized E set(int index, E element) {
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
…
get(int index)
作用:返回指定位置的元素
return elementData(index);
…
扩展知识点
Vector和ArrayList的区别?
- Vector是线程安全的
- 扩容增量不同
- ArrayList达到扩容条件后,扩容为原容量的1.5倍,Vector达到扩容条件后:
- 如果在构造函数中指定了扩容时增加的量(即capacityIncrement) 那么扩容公式是:
capacityIncrement + 原容量 = 新容量 - 没有指定扩容时增加的量, 默认值为0, 扩容公式是:原容量 + 原容量 = 新容量(即2倍)
- 如果在构造函数中指定了扩容时增加的量(即capacityIncrement) 那么扩容公式是:
- ArrayList达到扩容条件后,扩容为原容量的1.5倍,Vector达到扩容条件后: