Vector与ArrayList一样内部是由数组组成的,它也是一个动态数组,但是由于其内部实现了线程安全机制,所以在性能方面较差,使用的次数也没有ArrayList那样频繁,下面我们来看一看Vector的源码。
1.Vector的定义
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
与ArrayList一样,Vector继承了AbstractList,实现了List,RandomAccess,Cloneable与Serializable接口,所以它有着与ArrayList一样的功能。
2.Vector的属性
//Vector中用于保存数据的数组
protected Object[] elementData;
//Vector中数据的总量,也就是实际存储的数据的数量
protected int elementCount;
//Vector数组每次扩容时容器的增长量
protected int capacityIncrement;
3.Vector的构造函数
Vector 有四个构造函数,分别如下:
//该构造函数指定了Vector容器的初始大小和每次扩容时容器增长量
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
//可以看到该构造函数在初始化时新建了一个大小为 initialCapacity的数组,并为capacityIncrement赋值
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
//只指定容器初始化大小
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//默认初始化函数,用于构造容器大小为10的Vector
public Vector() {
this(10);
}
//参数为集合,用于生成一个新的Vector集合
public Vector(Collection<? extends E> c) {
//将集合c中的元素转换成为Vector中的数组元素
elementData = c.toArray();
//设置实际元素数量值
elementCount = elementData.length;
若elementData不为Object类型的数组,则将其转换成为Object类型的数组
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
4.Vector常用操作方法
4.1获取元素
//可以看到Vector中的方法都添加了synchronized关键字,因此它是线程同步的。
public synchronized E get(int index) {
//查看输入的下标是否越界
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
//这里获取元素的功能由elementData方法完成
return elementData(index);
}
//由于Vector本质就是数组,因此可以使用下标获取元素,返回elementData中下标为index的元素
E elementData(int index) {
return (E) elementData[index];
}
4.2添加元素
public synchronized boolean add(E e) {
modCount++;
//添加元素时,先对数组进行扩容
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
//这是一个私有的内部方法
private void ensureCapacityHelper(int minCapacity) {
//检查是否越界,若没有则让grow进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//设置Vector数组的最大长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
//获取没扩容前数组的长度
int oldCapacity = elementData.length;
//扩容后的Vector数组大小,若capacityIncrement大于0,则在原数组长度上增加capacityIncrement长度,若capacityIncrement小于0,则在原数组的长度基础上扩容一倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
//对扩容结果进行校验,minCapacity表示当前新数组所需的最小Vector数组长度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//若newCapacity超过了数组的最大容量,则由hugeCapacity构建
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//返回所能创建的数组的最大容量
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
//set方法为对Index下标的元素进行覆盖
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}
//直接将元素添加到Vector数组的末尾
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
//向Vector容器中批量添加元素
public synchronized boolean addAll(Collection<? extends E> c) {
modCount++;
//先将c容器中的元素转换成为object类型的数组
Object[] a = c.toArray();
int numNew = a.length;
//对Vector数组进行扩容
ensureCapacityHelper(elementCount + numNew);
//将c容器中的元素复制到Vector中
System.arraycopy(a, 0, elementData, elementCount, numNew);
//修改实际元素数量
elementCount += numNew;
return numNew != 0;
}
//与上面的addAll方法差不多,只不过该方法是在Vector指定位置Index处添加集合C的元素
public synchronized boolean addAll(int index, Collection<? extends E> c) {
modCount++;
//检查是否越界
if (index < 0 || index > elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
//numMoved为需要移动元素的个数
int numMoved = elementCount - index;
if (numMoved > 0)
//将原先Index处的numMoved个元素,向后移动到距离原位置numNew处
System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
elementCount += numNew;
return numNew != 0;
4.3删除元素
//用于移除Vector中的obj元素
public synchronized boolean removeElement(Object obj) {
modCount++;
//先用indexOf找到第一个值为obj元素的下标位置
int i = indexOf(obj);
if (i >= 0) {
//移除该下标
removeElementAt(i);
return true;
}
return false;
}
public int indexOf(Object o) {
return indexOf(o, 0);
}
//该方法用于移除元素值为o的元素
public synchronized int indexOf(Object o, int index) {
//Vector是允许元素值为null的
if (o == null) {
//从index开始向后进行遍历,找到第一个元素值为null的下标
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
//从index开始向后进行遍历,找到第一个元素值为o的下标
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
//该方法用于移除Vector中的所有元素
public synchronized void removeAllElements() {
modCount++;
// Let gc do its work
for (int i = 0; i < elementCount; i++)
elementData[i] = null;
elementCount = 0;
}
//移除指定位置index处的元素
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
//获取原先index处的值
E oldValue = elementData(index);
//需要移动的距离
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,numMoved);
elementData[--elementCount] = null;
return oldValue;
}
5一般常用方法
//该方法用于对Vector数组进行扩容
public synchronized void setSize(int newSize) {
modCount++;
//若新容器大小大于实际元素值,则扩容
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
//若小于,则将Vector后elementCount-newSize个元素删除
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
elementCount = newSize;
}
//返回Vector容器中实际元素个数
public synchronized int size() {
return elementCount;
}
//判断Vector容器是否为空
public synchronized boolean isEmpty() {
return elementCount == 0;
}
//返回所有的元素
public Enumeration<E> elements() {
//匿名函数
return new Enumeration<E>() {
int count = 0;
//是否还有元素
public boolean hasMoreElements() {
return count < elementCount;
}
//返回元素
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
//检查Vector中是否包含o对象
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
Vector就分析那么多, 一般情况下Vector使用的频率不是很高,所以要记住它与ArrayList的区别即可。