List集合实现——Vector
该集合是支持随机访问、支持集合大小可变,保证线程安全的运行环境。
该集合的基本结构包括一个数组、一个指向当前数组的可验证边界、一个扩容数组的参考值。
重要源码
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
*该数组主要用于存储Vector集合中的所有对象,容量可以扩展,多出来的数组位置上的值都为null
*/
protected Object[] elementData;
/**
*该变量主要用于记录当前Vector集合中的对象数量
*/
protected int elementCount;
/**
*该变量表示每次扩容的大小,如果该变量的值小于或等于0,扩容后的容量为原来的两倍
*/
protected int capacityIncrement;
/**
* 该构造方法可以设置集合的初始化大小和扩容容量,如果扩容容量为0,那么扩容量为当前的1倍
* @param initialCapacity
* @param capacityIncrement
*/
public Vector(int initialCapacity, int capacityIncrement){
super();
if (initialCapacity < 0){
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
/**
* 该构造方法可以设置集合的初始化大小,但是扩容变量为0
* @param initialCapacity
*/
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* 该集合默认的构造方法,初始化容量为10
*/
public Vector() {
this(10);
}
public synchronized E set(int index, E element) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index);
}
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
//告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
/**
* 删除指定元素,如果存在返回true,否则返回false
* @param o
* @return
*/
public boolean remove(Object o) {
return removeElement(o);
}
/**
* 删除指定元素,并将后面的元素(如果后面还有)前移一位
* @param obj
* @return
*/
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
/**
*
* @param index
*/
public synchronized void removeElementAt(int index) {
modCount++;
//指定索引大于集合的容量了
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
//要移动数组的长度
int j = elementCount - index - 1;
if (j > 0) {
/**
* elementData 要复制的源数组
* index + 1 从源数组中复制的起始位置
* elementData 进行数组复制的目标数组
* index在目标数组中复制的起始位置
* j 指定进行复制的长度
*/
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
/**
* 返回指定元素第一次出现的索引位置,如果集合不包含指定元素则返回-1
* @param o
* @return
*/
public int indexOf(Object o) {
return indexOf(o, 0);
}
/**
* 返回指定元素第一次出现的索引位置,如果集合不包含指定元素则返回-1
* @param o 指定元素
* @param index 开始索引
* @return
*/
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;
}
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
/**
* 判断数组是否已满,满了就扩容
* @param minCapacity
*/
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 - 8;
/**
* 数组扩容
* @param minCapacity
*/
private void grow(int minCapacity) {
// 数组的旧容量
int oldCapacity = elementData.length;
//新容量为旧容量加 如果capacityIncrement每次扩容容量大于0 ,否则加上旧容量
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//如果新容量小于 传入的容量,则设置新容量为传入的容量大小
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
//如果新容量-数组的最大容量大于0,即新容量大于数组最大容量
if (newCapacity - MAX_ARRAY_SIZE > 0) {
newCapacity = hugeCapacity(minCapacity);
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
// overflow 溢出
if (minCapacity < 0) {
throw new OutOfMemoryError();
}
// 如果 minCapacity 大于数组的最大长度则返回 int 可以具有的最大值的常数,否则返回分配数组的最大容量
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* 为集合设置新容量,如果新容量大于集合容量,则进行扩容;
* 如果新容量的值小于当前集合的元素,则将新容量之后索引位上的对象都设置为null
* @param newSize
*/
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
elementCount = newSize;
}
}