1.介绍
Vector同样继承自AbstractList,与ArrayList、LinedList一样,是List的一种实现,是线程安全的
2.类定义
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
继承AbstractList,实现List接口,相关信息,请查看之前的博客
3.成员变量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//最大容量
protected Object[] elementData;//Object数组,说明Vector底层实现是数组
protected int elementCount;//实际大小
protected int capacityIncrement;//动态数组的增长系数,扩容时增加大小为capacityIncrement
4.构造函数
//设定初始长度和扩容增长长度
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
/**
* Constructs an empty vector with the specified initial capacity and
* with its capacity increment equal to zero.
*
* @param initialCapacity the initial capacity of the vector
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
//设定初始长度构造
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* Constructs an empty vector so that its internal data array
* has size {@code 10} and its standard capacity increment is
* zero.
*/
//无参构造
public Vector() {
this(10);
}
/**
* Constructs a vector containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this
* vector
* @throws NullPointerException if the specified collection is null
//传入一个Collection对象进行构造
* @since 1.2
*/
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
5.添加元素
//添加元素,通过syncronized实现线程安全
public synchronized boolean add(E e) {
modCount++;
add(e, elementData, elementCount);
return true;
}
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)//需要扩容
elementData = grow();//扩容
elementData[s] = e;
elementCount = s + 1;
}
private Object[] grow() {
return grow(elementCount + 1);
}
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
//真正的扩容方法
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//在初始化Vector时,不指定增长系数capacityIncrement,那么扩容时,Vector的容量在原来 的基础上扩大1.0倍。如果我们指定增长系数capacityIncrement,那么扩容时,就按增长系数capacityIncrement的数字来扩大
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity <= 0) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
add(int,E)
//添加元素到指定位置
public void add(int index, E element) {
insertElementAt(element, index);
}
public synchronized void insertElementAt(E obj, int index) {
if (index > elementCount) {//判断是否越界
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
modCount++;
final int s = elementCount;
Object[] elementData = this.elementData;
if (s == elementData.length)//判断是否需要扩容
elementData = grow();//扩容:同上
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);//移动元素
elementData[index] = obj;
elementCount = s + 1;
}
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
/**
解析:src - 源数组。
srcPos - 源数组中的起始位置。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
该方法是用了native关键字,调用的为C++编写的底层函数,可见其为JDK中的底层函数。ArrayList于Vector大多都是使用该方法实现
*
**/
addAll方法和以上add方法基本类似,具体的可参考上述源码,自行阅读。
总结:
Vector作为List的一种实现,由于其与ArrayList一样使用对象数组来保存元素,所以其提供的方法与ArrayList基本类似,但是所有方法的定义都多了一个关键字synchronized,相信大家已经知道Vector存在的意义了,那么就是Vector是线程安全的。这也是它与ArrayList的根本区别。
这也决定了ArrayList和Vector在使用上的区别。由于ArrayList不考虑线程安全,所以在执行效率上,ArrayList是优于Vector的,所以在不需要考虑线程安全,或者永远都只会有一个线程能访问到List对象时,最好使用ArrayList,而在可能会有多个线层访问同一个List集合时,使用Vector无疑是最佳选择,因为它的实现已经考虑了线程安全的问题。但是往往在多线程情况下,我们却不用Vector,而是使用Collections.synchronizedList,CopyOnWriteArrayList