Vector源码分析
Vector的结构图
Vector的概述
Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
和ArrayList不同,Vector中的操作是线程安全的,Vector的线程安全通过在方法上直接加synchronized实现。扩容默认扩大为原来的2倍。
Vector的属性
// Object类型的数组
// 注意:访问修饰符有所不同,Vector用protected修饰,而ArrayList用private修饰。
// JavaSe中:private变量只能被当前类的方法访问,而protected可以被同一包中的所有类和其他包的子类访问
protected Object[] elementData;
// 动态数组的实际有效大小,即数组中存储的元素个数
protected int elementCount;
// 动态数组的增长系数:若开始事先没有指定,则默认是增加一倍的大小
protected int capacityIncrement;
// 序列版本号
private static final long serialVersionUID = -2767605614048989439L;
Vector的构造方法
// 默认空参构造函数
public Vector() {
// 调用指定初始容量的构造函数,初始容量为10
this(10);
}
// 可以指定初始容量的构造函数
public Vector(int initialCapacity) {
// 调用指定初始容量和增长系数的构造函数,增长系数设置为0
this(initialCapacity, 0);
}
// 可以指定初始容量和增长系数的构造函数
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
// 根据初始容量创建一个Object类型的数组
this.elementData = new Object[initialCapacity];
// 给增长系数赋值
this.capacityIncrement = capacityIncrement;
}
// 参数为集合类型的构造函数
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
// 将参数集合c 中的数据拷贝到elementData
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
Vector的方法
get方法
// 获得指定下标的元素数据
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
set方法
// 修改指定下标的元素数据
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
remove方法
// 删除某个元素数据
public boolean remove(Object o) {
return removeElement(o);
}
// 删除obj
public synchronized boolean removeElement(Object obj) {
modCount++;
// 找到指定元素的下标
int i = indexOf(obj);//调用indexOf找到指定位置,在下方
if (i >= 0) {
// 根据下标删除元素
removeElementAt(i);
return true;
}
return false;
}
// 根据下标删除元素
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
// index之后的有效元素数量
int j = elementCount - index - 1;
if (j > 0) {
// 旧数组替换新数组
System.arraycopy(elementData, index + 1, elementData, index, j);
}
// 有效元素数量--
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
public int indexOf(Object o) {
return indexOf(o, 0);
}
//从index开始寻找o,返回o第一次出现的索引
public synchronized int indexOf(Object o, int index) {
if (o == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
add方法
// 在数组末尾添加指定元素
public synchronized boolean add(E e) {
modCount++;
// 判断是否需要扩容
ensureCapacityHelper(elementCount + 1);//该方法将会在扩容部分讲解
elementData[elementCount++] = e;
return true;
}
element相关的方法
//将指定的组件添加到此向量的末尾,将其大小增加 1。如果向量的大小比容量大,则增大其容量。
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
//返回指定索引处的组件。 其实这个方法就是和我们之前使用的get方法很相似。源码很简单,就是说先进行一个index的有效位检验,如果正确在进入elementData(int index)方法,直接取数组的数据。
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
//返回此向量的组件的枚举。返回的 Enumeration 对象将生成此向量中的所有项。生成的第一项为索引 0 处的项,然后是索引 1 处的项,依此类推。这个和遍历时候用的Iterator很相似。
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");
}
};
}
element相关的方法与之前的add,get方法相似,还有的就不在这列出,可自行观看源码。
其他方法
// 将数组Vector中的全部元素都拷贝到数组anArray中去,调用本地方法arraycopy
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
//将集合的容量修剪为集合的当前大小
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
// 设置Vector数组的大小
public synchronized void setSize(int newSize) {
// 修改次数++
modCount++;
// 判断设置的数组大小是否大于Vector中存储的有效元素的个数
// 若 newSize > Vector中有存储的效元素的个数,则调整Vector的大小
if (newSize > elementCount) {
// 调用判断是否扩容的方法,如果需要扩容则该方法内部调用扩容方法grow()
ensureCapacityHelper(newSize);
} else {
// 如果上述判断不成立,则将newSize位置之后开始的元素都设置为null
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
// 更新有效元素个数
elementCount = newSize;
}
// 获取Vector的当前容量
public synchronized int capacity() {
return elementData.length;
}
// 获取Vector里面的有效元素个数
public synchronized int size() {
return elementCount;
}
// 判断Vecotor中是否包含元素 o
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
......
扩容方法(重要)
// 确定数组当前的容量大小
public synchronized void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
modCount++;
ensureCapacityHelper(minCapacity);
}
}
// 如果:当前容量 > 当前数组长度,就调用grow(minCapacity)方法进行扩容
// 由于该方法是在ensureCapacity()中被调用的,而ensureCapacity()方法中已经加上了synchronized锁,所以
// 该方法不需要再加锁
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 最大上限的数组容量大小
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE
// Vector集合中的核心扩容方法
private void grow(int minCapacity) {
// overflow-conscious code
// 获取旧数组的容量
int oldCapacity = elementData.length;
// 得到扩容后(如果需要扩容的话)的新数组容量
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);//可自定义扩容大小,默认为2倍(oldCapacity + oldCapacity)
// 如果新容量 < 数组实际所需容量,则令newCapacity = minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果当前所需容量 > MAX_ARRAY_SIZE,则新容量设为 Integer.MAX_VALUE,否则设为 MAX_ARRAY_SIZE
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;
}