/**
* The {@code Vector} class implements a growable array of
* objects. Like an array, it contains components that can be
* accessed using an integer index. However, the size of a
* {@code Vector} can grow or shrink as needed to accommodate
* adding and removing items after the {@code Vector} has been created.
*
* <p>Each vector tries to optimize storage management by maintaining a
* {@code capacity} and a {@code capacityIncrement}. The
* {@code capacity} is always at least as large as the vector
* size; it is usually larger because as components are added to the
* vector, the vector's storage increases in chunks the size of
* {@code capacityIncrement}. An application can increase the
* capacity of a vector before inserting a large number of
* components; this reduces the amount of incremental reallocation.
*
* <p><a name="fail-fast"/>
* The iterators returned by this class's {@link #iterator() iterator} and
* {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
* if the vector is structurally modified at any time after the iterator is
* created, in any way except through the iterator's own
* {@link ListIterator#remove() remove} or
* {@link ListIterator#add(Object) add} methods, the iterator will throw a
* {@link ConcurrentModificationException}. Thus, in the face of
* concurrent modification, the iterator fails quickly and cleanly, rather
* than risking arbitrary, non-deterministic behavior at an undetermined
* time in the future. The {@link Enumeration Enumerations} returned by
* the {@link #elements() elements} method are <em>not</em> fail-fast.
*
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification. Fail-fast iterators
* throw {@code ConcurrentModificationException} on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: <i>the fail-fast behavior of iterators
* should be used only to detect bugs.</i>
*
* <p>As of the Java 2 platform v1.2, this class was retrofitted to
* implement the {@link List} interface, making it a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>. Unlike the new collection
* implementations, {@code Vector} is synchronized. If a thread-safe
* implementation is not needed, it is recommended to use {@link
* ArrayList} in place of {@code Vector}.
*
* @author Lee Boynton
* @author Jonathan Payne
* @see Collection
* @see LinkedList
* @since JDK1.0
*/
- Vector实现了一个可扩展的数组对象。和普通数组一样,它的元素可以通过整型下标访问得到。Vector被新建之后,其大小随着增加或删除元素而增长或减小。
- 每一个vector通过容量和容量增长两个参数来优化平衡数组的大小。容量值至少和元素个数相同,但是容量值通常比元素个数大,因为会有元素增加到数组中,还有就是数组增长的幅度是以capacityIncrement为单位的。当插入大量的元素到数组中时,这个方法可以减少数组重置的次数。
- “快失败准则”:如果此数组的迭代器被创建之后,数组结构依然在被改动,此刻迭代器将会抛出ConcurrentModificationException异常。遍历数组的另一个方法Enumerations,这个方法是没有执行“快失败准则”的。
- 需要注意的是,迭代器的快失败行为不能保证同步修改安全。因此,凭借程序是否抛出这个异常来判别程序的准确性是不可取的。迭代器的快失败行为只能用来检验debug
- 如果程序不要求是多线程安全的话,建议使用ArrayList而不是vector
protected Object[] elementData;
注解字段:这个数组缓存vector中的所有元素,vector的容量和这个数组的大小是一样的,因此这个数组至少能容下vector的所有元素
protected int elementCount;
注解字段:vector中合法元素的个数
protected int capacityIncrement;
注解字段:当vector的元素个数大于capacity的时候,vector的capacity是自动增长的,扩容单位是capacityIncrement。如果初始化的时候这个值小于等于0,则当vector需要扩容的时候,扩容单位是当前capacity的二倍。
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
注解方法:使用给定参数initialCapacity和capacityIncrement来构造一个空vector,如果初始容量低于0的时候,将会报出IllegalArgumentException异常
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
注解方法:使用给定参数initialCapacity和capacityIncrement=0来构造一个空vector。因为capacityIncrement=0,因此扩容的方法是当前容量*2。 同样的初始容量不能小于0
public Vector() {
this(10);
}
注解方法:构造一个初始容量是10,扩容方法是乘以2
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)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
注解方法:构造一个vector来存放给定集合元素,细节方面主要是首先将集合转化为数组,将此数组的元素复制到给定初始数组中。
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
注解方法:将现有的vector中的元素全部复制到给定的数组中。
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
注解方法:这个方法简单说就是保证咱vector占用最少存储空间,截取掉不需要的空间。
public synchronized void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
modCount++;
ensureCapacityHelper(minCapacity);
}
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
注解方法:这两个方法是判断vector是否需要扩容,minCapacity是现在vector需要的最小存储空间,elementData.length是当前vector的现有空间,如果需要的最小存储空间大于现有的空间时候,vector就需要扩容了。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
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;
}
注解方法:这两个方法就是详细的扩容过程。首先获取当前的vector容量,然后根据参数capacityIncrement来决定扩容之后的容量(如果参数小于等于0,则扩容的速度是当前容量的二倍,否则则正常扩容,oldCapacity+capacityIncrement)。接下来,如果新的容量依旧低于vector需要的最低容量的时候,即将赋予新容量为真正需求容量。紧接着这种情况发生的概率很低,所以咱们可以直接忽视。最后和之前一样,将现有的元素全部复制到扩容后的vector中。
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;
}
注解方法:设置vector数组的大小,如果这个size大于现有的vector的大小,则将插入null填补空缺。如果现有元素的个数多余newSize的话,则将newSize后面的元素直接弃之。
public synchronized int capacity() {
return elementData.length;
}
注解方法:获取当前vector的容量
public synchronized int size() {
return elementCount;
}
注解方法:这是获取当前vector中元素的个数,和上一个方法一定要区别开来
public synchronized boolean isEmpty() {
return elementCount == 0;
}
注解方法:判断该vector是否没有元素
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的元素,需要注意的是这种方法不会产生快失败的行为。
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
public int indexOf(Object o) {
return indexOf(o, 0);
}
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;
}
注解方法:这三个方法要放在一起看,首先第一个方法是用来判断vector中是否存在给定元素,他所调用的方法是第二个方法。第二个方法是为了范围给定元素在vector中的位置,这个位置计算的方法是调用indexOf方法。我们来看看indexOf方法,首先如果给定元素是null,则遍历整个vector,如果存在直接返回位置,否则返回-1;如果给定元素不是null的话,同样遍历整个vector,返回给定元素的位置。这样再回到第一个方法,他是直接寻找给定元素在vector中的位置,如果位置为-1的话,直接告知调用者不存在这个元素,否则就返回true
public synchronized int lastIndexOf(Object o) {
return lastIndexOf(o, elementCount-1);
}
public synchronized int lastIndexOf(Object o, int index) {
if (index >= elementCount)
throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
if (o == null) {
for (int i = index; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
注解方法:先说第二个方法吧,给定两个参数其中index是指从vector中的index位置,开始向前遍历vector,查看最后一次出现object的位置,如果不存在则返回-1.然后第一个方法就好理解了,它是在整个vector中搜索object最后一次出现的位置。需要注意的是其中index如果大于等于vector中元素的个数,就会抛出数组越界的异常。
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
注解方法:输出vector中给定位置的元素,首先也是会判断index是否越界
public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
注解方法:输出vector中第一个元素,如果vector中没有元素,则会抛出异常
public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
注解方法:输出vector中最后一个元素,同样,如果vector中没有元素,也会抛出异常
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}
注解方法:将index位置上元素,替换为指定元素。首先也要判断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) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
注解方法:移除index位置上的元素。首先判断index是否越界,越界则抛出异常。如果没有越界的话,则删除index位置的元素,并将index位置后面的元素全往前复制一个位置,并且将最后一个位置设置为null
public synchronized void insertElementAt(E obj, int index) {
modCount++;
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
elementData[index] = obj;
elementCount++;
}
注解方法:在指定位置插入元素。如果插入的位置大于元素的个数,就会抛出异常。因为要插入元素,所以首先要做的就是扩容判断的相关操作,前面已经介绍过了。然后将vector的元素从index位置全部向后复制,然后index位置设置为指定元素。
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
注解方法:在vector的最后一个位置插入元素。同样的,在插入之前也执行扩容判断的相关操作。
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
注解方法:是否可以移除指定的元素。首先调用之前的indexOf方法,获取obj的位置,如果存在这个位置,则调用removeElementAt方法,直接移除该元素,然后返回true。否则就会返回false
public synchronized void removeAllElements() {
modCount++;
// Let gc do its work
for (int i = 0; i < elementCount; i++)
elementData[i] = null;
elementCount = 0;
}
方法注解:移除vector的所有元素。将所有的元素置为null,然后垃圾回收器会回收他,最后别忘记vector中元素个数为0
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
注解方法:返回指定位置的元素。首先会判断指定位置是否越界
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
注解方法:用特定元素取代特定位置的元素,并返回旧值。需要注意的是,只要用到位置的地方,都需要判断位置是否出现异常
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
注解方法:在vector最后添加元素。首先进行扩容判断处理,然后在最后添加元素。
public boolean remove(Object o) {
return removeElement(o);
}
注解方法:判断是否可以移除vector中的指定元素,如果有多个这个元素,则移除元素在vector中第一次出现的地方
public void add(int index, E element) {
insertElementAt(element, index);
}
注解方法:在指定位置添加指定元素。调用的insertElementAt方法
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work
return oldValue;
}
注解方法:移除指定位置的元素,并返回该值。所有也会判断index是否数组越界。移除某个元素之后,将此位置之后的元素全部向前复制一个位置,并将最后一个位置置为null,交给垃圾回收器回收。
public void clear() {
removeAllElements();
}
注解方法:调用removeAllElements方法,清除vector所有元素
public synchronized boolean containsAll(Collection<?> c) {
return super.containsAll(c);
}
注解方法:判断vector中是否包含指定集合中的所有元素。调用父类中的containsAll方法,这个方法是逐个判断vector是否包含集合元素
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);
int numMoved = elementCount - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
elementCount += numNew;
return numNew != 0;
}
注解方法:在vector中的index处,插入指定集合的所有元素。首先这个方法会判断index是否越界,然后将集合转化为数组,先扩容机制检查,然后将vector中从index位置到最后的元素全部复制到新数组的index+numNew到最后的位置。然后再复制给定集合到新vector的index到index+numNew位置。