基本介绍
Vector位于java.util包,于JDK1.0引入,对于List的实现接口,比ArrayList和LinkedList引入还要早,算是JDK的早期实现。Vector的底层也是通过数组实现。查看UML类图:
关于Vector的历史,源码中有一段介绍:
As of the Java 2 platform v1.2, this class was retrofitted to implement the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
Vector的出现要早于集合框架,在JDK1.2开始,Vector被重构为List的实现类之一,成为集合框架的成员。与新的集合实现不同,Vector 是同步的。如果不需要线程安全实现,建议使用 ArrayList 代替 Vector。
然后在实际应用中,即使需要使用同步的List实现也很少再使用Vector,已经被Collections.SynchronizedList或者CopyOnWriteArrayList替代。
源码分析
构造方法
Vector中包含了三个重要的成员变量
// 存储数据元素的Object类型数组
protected Object[] elementData;
// elementData实际拥有元素的大小
protected int elementCount;
// 当Vector的大小变得大于其容量时,自动扩充容量长度的值
// 如果容量增量小于或等于零,则每次需要增长时,向量的容量都会增加一倍。
protected int capacityIncrement;
查看构造方法源码
// 无参构造,默认初始化长度为10
public Vector() {
this(10);
}
// 指定初始化长度的构造方法,默认自动增长长度为0
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
// 指定初始化长度及自动增长长度的构造方法
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
add
Vector使用的是数组结构实现,使用add方法直接添加元素,是在数组结尾设置,查看源码,整个方法快被关键字所synchronized修饰,因此是线程安全的,但是也损失了一部分性能。
public synchronized boolean add(E e) {
// 记录Vector修改的次数,继承自AbstractList抽象类
modCount++;
// 确保容量可以存放数据
ensureCapacityHelper(elementCount + 1);
// 将元素存储在当前elementCount递增1下标对应的位置
elementData[elementCount++] = e;
return true;
}
接下来查看ensureCapacityHelper方法如何校验数组长度,以及进行扩容
private void ensureCapacityHelper(int minCapacity) {
// 如果传入的下标位置比当前elementData数组长度小,调用grow方法进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
查看grow方法源码
private void grow(int minCapacity) {
// 记录当前数组的长度为oldCapacity
int oldCapacity = elementData.length;
// 判断增长因子capacityIncrement是否大于0
// 如果capacityIncrement>0,新的长度为oldCapacity+capacityIncrement
// 如果capacityIncrement<=0,新的长度为oldCapacity+oldCapacity
// 当第一次调用add方法时
// oldCapacity=10,newCapacity=10+10=20,即第一次调用add时,Vector会扩容至两倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 此处的hugeCapacity方法以及MAX_ARRAY_SIZE同ArrayList
newCapacity = hugeCapacity(minCapacity);
// 调用Arrays的copyOf方法,原理同ArrayList
elementData = Arrays.copyOf(elementData, newCapacity);
}
- 与ArrayList中相同部分可参考:https://www.yuque.com/starsray/java/udywoi
insertElementAt
insertElementAt方法可以在指定位置插入元素,查看源码
Vector中同样支持add方法在指定位置设置元素,其底层使用的仍是insertElementAt方法,查看源码public synchronized void insertElementAt(E obj, int index) {
modCount++;
// 如果index值大于当前数组中元素的个数,抛出数组越界异常
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
// 调用ensureCapacityHelper检查数组长度是否需要扩容
ensureCapacityHelper(elementCount + 1);
// 调用系统的arraycopy方法,并替换指定位置的元素
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
// 设置数组下标index处为指定元素obj
elementData[index] = obj;
// 数组元素个数++
elementCount++;
}
public void add(int index, E element) {
insertElementAt(element, index);
}
总结
Vector在JDK1.0版本出现,在JDK1.2中作为List的实现类,并入到集合框架大家庭中。其底层实现是基于数组实现的,相比于ArrayList,Vector是线程安全的,二者的扩容机制有所不同。
Vector是一种古老传统的List实现,基本上已经被淘汰,由于方法都是同步方法,因此执行效率比较低,与其他List成员相比,Vector的增长因子可以手动指定。