Java容器源码-Vector

时间:2021-05-15 04:21:25

前几天学习了ArrayList源码迭代器模式在ArrayList源码中的使用,今天开始学习Vector源码。参考的JDK版本为1.8。

相信大家对Vector的使用已经很熟悉了,它和ArrayList的最大的不同是它是线程安全的,这点在Vector源码中也有说明。Vector源码中注释有这么一句“Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector”,意为“Vector 是同步的。如果不需要线程安全的实现,推荐使用ArrayList代替Vector”。Vector 是如何线程安全的?除了线程安全之外,它和ArrayList 还有其他不同吗?本文将分析Vector 的内部结构及实现原理,帮助大家更好的使用它。

Vector 层次结构图

先来看看ArrayList的定义

public class Vector<E> extends AbstractList<E> implements List<E>,RandomAccess, Cloneable, java.io.Serializable

从中我们可以了解到

  • Vector<E>:说明它支持泛型
    extends AbstractList<E> implements List<E>:说明它继承了extends AbstractList<E>,并实现了implements List<E>。
    implements RandomAccess:表明其支持快速(通常是固定时间)随机访问。此接口的主要目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能。下面是JDK1.8中对RandomAccess的介绍:
Marker interface used by <tt>List</tt> implementations to indicate that they support fast (generally constant time) random access.  The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.
  • implements Cloneable:表明其可以调用clone()方法来返回实例的field-for-field拷贝。
  • implements java.io.Serializable:表明该类是可以序列化的。

但继承实现信息还不够完整,我建议大家以后查看一个类的继承实现关系的时候,使用类结构层次图。

Java容器源码-Vector

如何查看类层次结构图可以参考我写过的一篇文章:

eclipse-查看继承层次图/继承实现层次图

全局变量

/**
* 保存vector中元素的数组。vector的容量是数组的长度,数组的长度最小值为vector的元素个数。
*
* 任何在vector最后一个元素之后的数组元素是null。
*
* @serial
*/

protected Object[] elementData;

/**
* vector中实际的元素个数。
*
* @serial
*/

protected int elementCount;

/**
* vector需要自动扩容时增加的容量。
*
* 当vector的实际容量elementCount将要大于它的最大容量时,vector自动增加的容量。
*
* 如果capacityIncrement小于或等于0,vector的容量需要增长时将会成倍增长。
* @serial
*/

protected int capacityIncrement;

/**
* 序列版本号
*/

private static final long serialVersionUID = -2767605614048989439L;

构造方法

接下来,看Vector提供的构造方法。ArrayList提供了四种构造方法。

1.构造一个指定容量为capacity、自增容量为capacityIncrement的空vector。

/**
* 构造一个指定容量为initialCapacity、自增容量为capacityIncrement的空vector。
*
* @param initialCapacity 初始化容量
* @param capacityIncrement 自增容量
*
* @throws IllegalArgumentException 如果initialCapacity是负数
*/

public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}

2.构造一个指定容量为initialCapacity、自增容量为0的空vector。

/**
* 构造一个指定容量为initialCapacity、自增容量为0的空vector。
*
* @param initialCapacity 初始化容量
* @throws IllegalArgumentException 如果initialCapacity是负数
*/

public Vector(int initialCapacity) {
this(initialCapacity, 0);
}

3.构造一个指定容量为10、自增容量为0的空vector。

/**
* 构造一个指定容量为10、自增容量为0的空vector。
*/

public Vector() {
this(10);
}

4.使用指定的Collection构造vector。

/**
* 构造一个包含特定Collection中所有元素的vector。
*
* @param c 用来构造vector的Collection
*
* @throws NullPointerException 用来构造vector的Collection是null
*
* @since 1.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);
}

方法

copyInto

/**
* 将vector中的所有元素拷贝到指定的数组anArray中
*
* @param anArray 指定的数组anArray,用来存放vector中的所有元素
*
* @throws NullPointerException 如果指定的数组anArray为null
* @throws IndexOutOfBoundsException 如果指定的数组anArray的容量小于vector的元素个数
* @throws ArrayStoreException 如果vector不能被拷贝到anArray中
* @see #toArray(Object[])
*/

public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}

trimToSize()

/**
* 将底层数组的容量调整为当前vector实际元素的个数,来释放空间。
*/

public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
////当实际大小小于底层数组的长度
if (elementCount < oldCapacity) {
//将底层数组的长度调整为实际大小
elementData = Arrays.copyOf(elementData, elementCount);
}
}

ensureCapacity

该方法的实现和ArrayList中大致相同。不同的是在第一次扩容时,vector的逻辑是:
newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);

即如果capacityIncrement>0,就加capacityIncrement,如果不是就增加一倍。
而ArrayList的逻辑是:
newCapacity = oldCapacity + (oldCapacity >> 1);
即增加现有的一半。

/**
* 增加vector容量
* 如果vector当前容量小于至少需要的容量,它的容量将增加。
*
* 新的容量将在旧的容量的基础上加上capacityIncrement,除非capacityIncrement小于等于0,在这种情况下,容量将会增加一倍。
*
* 增加后,如果新的容量还是小于至少需要的容量,那就将容量扩容至至少需要的容量。
*
* @param minCapacity 至少需要的容量
*/

public synchronized void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
modCount++;
ensureCapacityHelper(minCapacity);
}
}


/**
* ensureCapacity()方法的unsynchronized实现。
*
* ensureCapacity()是同步的,它可以调用本方法来扩容,而不用承受同步带来的消耗
*
* @see #ensureCapacity(int)
*/

private void ensureCapacityHelper(int minCapacity) {
// 如果至少需要的容量 > 数组缓冲区当前的长度,就进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

/**
* 分派给arrays的最大容量
* 为什么要减去8呢?
* 因为某些VM会在数组中保留一些头字,尝试分配这个最大存储容量,可能会导致array容量大于VM的limit,最终导致OutOfMemoryError。
*/

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
* 扩容,保证vector至少能存储minCapacity个元素。
* 首次扩容时,newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);即如果capacityIncrement>0,就加capacityIncrement,如果不是就增加一倍。
*
* 如果第一次扩容后,容量还是小于minCapacity,就直接将容量增为minCapacity。
*
* @param minCapacity 至少需要的容量
*/

private void grow(int minCapacity) {
// 获取当前数组的容量
int oldCapacity = elementData.length;
// 扩容。新的容量=当前容量+当前容量/2.即将当前容量增加一倍
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) {
//如果minCapacity<0,抛出异常
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
//如果想要的容量大于MAX_ARRAY_SIZE,则分配Integer.MAX_VALUE,否则分配MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

setSize

/**
* 设置vector的容量。
*
* 如果newSize大于现有vector的元素的个数,则将vector的大小设置为newSize。如果newSize小于现有vector的元素的个数,则将vector中索引在newSize(包括newSize)之后的元素都置为null。
*
* @param newSize 设置容量后的新大小
* @throws ArrayIndexOutOfBoundsException 如果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;
}

capacity

/**
* 返回当前vector的实际容量。
*
* @return 返回当前vector的实际容量。
*/

public synchronized int capacity() {
return elementData.length;
}

size

/**
* 查看vector中元素的实际个数。
*
* @return vector中元素的实际个数
*/

public synchronized int size() {
return elementCount;
}

isEmpty

/**
* 检测vector中是否有元素.
*
* @return 如果没有元素,返回true
*/

public synchronized boolean isEmpty() {
return elementCount == 0;
}

elements

/**
* 返回vector中所有元素的Enumeration。
*
* Enumeration提供用于遍历vector中所有元素的方法
*
* @return 返回vector中所有元素的Enumeration。
* @see 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");
}
};
}

contains

/**
* 查看vector中是否包含元素o。
*
* @param o 元素o
* @return vector中是否包含元素o
*/

public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}

indexOf

/**
* 正向遍历vector,返回第一次出现元素o的索引。
*
* 如果vector中不包含元素o,返回-1
*
* @param o 需要查找的元素
* @return 返回第一次出现元素o的索引。如果vector中不包含元素o,返回-1
*/

public int indexOf(Object o) {
return indexOf(o, 0);
}

indexOf

/**
* 从索引为index的位置正向遍历vector,返回第一次出现元素o的索引。
*
* 如果vector中不包含元素o,返回-1
*
* @param o 想要查找的元素
* @param index 开始查找位置的索引
* @return 返回第一次出现元素o的索引。如果vector中不包含元素o,返回-1
* @throws IndexOutOfBoundsException 如果index为负数
* @see Object#equals(Object)
*/

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;
}

lastIndexOf

/**
* 逆向遍历vector,返回第一次出现元素o的索引。
*
* 如果vector中不包含元素o,返回-1
*
* @param o 需要查找的元素
* @return 返回第一次出现元素o的索引。如果vector中不包含元素o,返回-1
*/

public synchronized int lastIndexOf(Object o) {
return lastIndexOf(o, elementCount-1);
}

lastIndexOf

/**
* 从索引为index的位置逆向遍历vector,返回第一次出现元素o的索引。
*
* 如果vector中不包含元素o,返回-1
*
* @param o 想要查找的元素
* @param index 开始查找位置的索引
* @return 返回第一次出现元素o的索引。如果vector中不包含元素o,返回-1
* @throws IndexOutOfBoundsException 如果index大于或等于vector的大小
*/

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;
}

elementAt

/**
* 返回索引为index的元素。
*
* @param index 查找的元素的索引
* @return 索引为index的元素
* @throws ArrayIndexOutOfBoundsException 索引小于0或大于vector的大小
*/

public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}

return elementData(index);
}

firstElement

/**
* 返回vector的第一个元素
*
* @return vector的第一个元素
* @throws NoSuchElementException 如果vector没有元素
*/

public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}

lastElement

/**
* 返回vector的最后一个元素
*
* @return vector的最后一个元素
* @throws NoSuchElementException 如果vector没有元素
*/

public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}

setElementAt

/**
* 替换索引为index的元素为指定的对象0
*
* 索引必须大于等于0而且小于vector的大小
*
* @param obj 指定的对象0
* @param index 被替换元素的索引
* @throws ArrayIndexOutOfBoundsException 索引必须小于等于0或者大于vector的大小
*/

public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}

removeElementAt

/**
* 删除在特定索引index的元素。在索引index之后的元素左移,索引减1。
*
* 索引index大小必须大于等于0且小于vector的大小
*
* @param index 需要删除的元素的索引
* @throws ArrayIndexOutOfBoundsException 索引index小于0或大于vector的大小
*/

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 */
}

insertElementAt

/**
* 在指定索引index处插入指定对象obj。索引大于或等于index的元素右移,索引+1。
* 索引必须大于等于0而且小于等于vector的大小。
*
* @param obj 指定对象
* @param index 指定索引
* @throws ArrayIndexOutOfBoundsException 索引小于0或者大于vector的大小
*/

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++;
}

addElement

/**
* 在vector的末尾添加指定元素obj,vector大小+1. 如果容量大与现有容量,要扩充容量。
*
* @param obj 要添加的对象
*/

public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}

removeElement

/**
* 正向遍历vector,当指定元素obj第一次出现时,删除它,它之后的元素左移一位。
*
* @param obj 要删除的元素
* @return 如果指定对象obj在vector存在,返回true。否则返回false。
*/

public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}

removeAllElements

/**
* 删除vector中所有元素,并将大小置为0。
*/

public synchronized void removeAllElements() {
modCount++;
// Let gc do its work
for (int i = 0; i < elementCount; i++)
elementData[i] = null;

elementCount = 0;
}

clone

/**
* 返回当前vector的克隆. 该克隆会指向一个全新的vector。
*
* @return 当前vector的克隆
*/

public synchronized Object clone() {
try {
@SuppressWarnings("unchecked")
Vector<E> v = (Vector<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, elementCount);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}

toArray

/**
* 将vector中所有元素按顺序存放到数组中
*
* @since 1.2
*/

public synchronized Object[] toArray() {
return Arrays.copyOf(elementData, elementCount);
}

toArray

/**
* 返回Vector的模板数组。所谓模板数组,即可以将T设为任意的数据类型。
*
* @param a 将要存放vector中所有元素的数组
* @return 存放vector中所有元素的数组
* @throws ArrayStoreException 如果vector中元素不能转换为T
* @throws NullPointerException 如果指定的数组为null
* @since 1.2
*/

@SuppressWarnings("unchecked")
public synchronized <T> T[] toArray(T[] a) {
//如果数组a的大小 < vector的元素个数
if (a.length < elementCount)
// 则新建一个T[]数组,数组大小是“Vector的元素个数”,并将“Vector”全部拷贝到新数组中
return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
//若数组a的大小 >= vector的元素个数,则将Vector的全部元素都拷贝到数组a中。
System.arraycopy(elementData, 0, a, 0, elementCount);

if (a.length > elementCount)
a[elementCount] = null;

return a;
}

elementData

// 获取索引为index的元素
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}

get

/**
* 返回vector中索引位置为index的元素.
*
* @param index 要返回的元素的索引
* @return 索引为index的元素
* @throws ArrayIndexOutOfBoundsException 如果索引小于0或者索引大于等于vector的大小
*
* @since 1.2
*/

public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);

return elementData(index);
}

set

/**
* 将索引为index的元素替换为指定元素element,并返回被替换的旧元素。
*
* @param index 被替换的元素的位置
* @param element 指定元素
* @return 被替换的旧元素
* @throws ArrayIndexOutOfBoundsException 如果索引小于0或者索引大于等于vector的大小
* @since 1.2
*/

public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);

E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}

add

/**
* 添加指定元素到vector的末尾.
*
* @param e 被添加到vector的元素
* @return true
* @since 1.2
*/

public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}

remove

/**
* 正向遍历vector,当指定对象o第一次出现时,删除它,它之后的元素左移一位。
*
* @param o 被删除的元素
* @return 如果对象在vector中存在,返回true
* @since 1.2
*/

public boolean remove(Object o) {
return removeElement(o);
}

add

/**
* 在指定索引index处插入指定对象element。索引大于或等于index的元素右移,索引+1。
* 索引必须大于等于0而且小于等于vector的大小。
*
* @param index 指定索引
* @param element 指定对象element
* @throws ArrayIndexOutOfBoundsException 索引必须小于0或者大于vector的大小
* @since 1.2
*/

public void add(int index, E element) {
insertElementAt(element, index);
}

remove

/**
* 删除在特定索引index的元素。在索引index之后的元素左移,索引减1。
*
* 索引index大小必须大于等于0且小于vector的大小
*
* @param index 需要删除的元素的索引
* @throws ArrayIndexOutOfBoundsException 索引index小于0或大于vector的大小
* @since 1.2
*/

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;
}

clear

/**
* 清空vector
*
* @since 1.2
*/

public void clear() {
removeAllElements();
}

containsAll

// 大数据量操作

/**
* 返回vector是否完全包含指定的集合c
*
* @param c 指定的集合c
* @return 返回vector是否完全包含指定的集合c
* @throws NullPointerException 指定的集合c为null
*/

public synchronized boolean containsAll(Collection<?> c) {
return super.containsAll(c);
}

addAll

/**
* 添加指定集合c中的所有元素到vector的末尾
*
* @param c 指定集合c
* @return 如果指定集合c的长度大于0
* @throws NullPointerException 如果指定集合c为null
* @since 1.2
*/

public synchronized boolean addAll(Collection<? extends E> c) {
modCount++;
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
System.arraycopy(a, 0, elementData, elementCount, numNew);
elementCount += numNew;
return numNew != 0;
}

removeAll

/**
* 删除vector中vector和指定集合c*有的元素。
*
* @param c 指定集合c
* @return true 如果删除成功
* @throws ClassCastException 如果vector中有元素和指定集合中的元素类型不匹配
* @throws NullPointerException 如果vector中含有null,而指定集合不支持null
* @since 1.2
*/

public synchronized boolean removeAll(Collection<?> c) {
return super.removeAll(c);
}

retainAll

/**
* 从vector中移除未包含在指定集合c中的所有元素
* @param c 指定集合c
* @return
* @throws ClassCastException 如果vector和指定集合中有元素类型不匹配
* @throws NullPointerException 如果vector中含有null,而指定集合不支持null
* @since 1.2
*/

public synchronized boolean retainAll(Collection<?> c) {
return super.retainAll(c);
}

addAll

/**
* 在vector的指定索引index处插入指定集合c。在索引index处的元素和之后的元素右移一位。
*
* @param index 指定索引
* @param c 指定集合
* @return
* @throws ArrayIndexOutOfBoundsException 索引index小于0或大于vector的大小
* @throws NullPointerException 指定的集合为null
* @since 1.2
*/

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;
}

**

 /**
*
* 比较指定的对象o和vector是否相等。
*
* 当特定的集合也是个list,而且和vector大小相等、元素相同,元素的顺序也相同,那么就可以说两者是相等的。
*
* @param o 和vector相比较的对象
* @return true 如果特定的对象和vector相等
*/

public synchronized boolean equals(Object o) {
return super.equals(o);
}

hashCode

/**
* 返回vector的hash code值.
*/

public synchronized int hashCode() {
return super.hashCode();
}

toString

/**
* 返回vector的字符串表示,包含每个元素的字符串表示
* Returns a string representation of this Vector, containing
* the String representation of each element.
*/

public synchronized String toString() {
return super.toString();
}

**

/**
* 返回一个list从起点索引fromIndex(包括)到终点索引toIndex(不包括)的子集。如果fromIndex等于endIndex,返回的子集为空。该子集是由list返回的,改变该子集会影响到list,反之亦然。子集支持list所有的操作。
*
* @param fromIndex 起点索引
* @param toIndex 终点索引
* @return 返回list的子集
* @throws IndexOutOfBoundsException 如果fromIndex小于0或者endIndex大于0
* @throws IllegalArgumentException 如果fromIndex大于toIndex
*/

public synchronized List<E> subList(int fromIndex, int toIndex) {
return Collections.synchronizedList(super.subList(fromIndex, toIndex),this);
}

removeRange

/**
* 删除list中从索引fromInde(包含)到toIndex(不包含)之间的所有元素。Removes from this list all of the elements whose index is between。索引toIndex处的元素和其之后的元素左移。
*/

protected synchronized void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = elementCount - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);

// Let gc do its work
int newElementCount = elementCount - (toIndex-fromIndex);
while (elementCount != newElementCount)
elementData[--elementCount] = null;
}

writeObject

注意Vector只有writeObject,而不像ArrayList既有writeObject,又有readObject。

/**
* 将vector写入到ObjectOutputStream中。
*
* 该方法执行同步以确定序列化数据的连贯性。
*/

private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
final java.io.ObjectOutputStream.PutField fields = s.putFields();
final Object[] data;
synchronized (this) {
fields.put("capacityIncrement", capacityIncrement);
fields.put("elementCount", elementCount);
data = elementData.clone();
}
fields.put("elementData", data);
s.writeFields();
}

listIterator

/**
* 返回一个vector的迭代器,开始指向索引为index的元素。
*
* @throws IndexOutOfBoundsException 如果index小于0或者大于vector大小。
*/

public synchronized ListIterator<E> listIterator(int index) {
if (index < 0 || index > elementCount)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}

ListItr的具体实现请往下看。

listIterator

/**
* 返回一个vector的迭代器,开始指向索引为0的元素。
*
* 返回的listIterator是fail-fast。
*
* @see #listIterator(int)
*/

public synchronized ListIterator<E> listIterator() {
return new ListItr(0);
}

ListItr的具体实现请往下看。

iterator

/**
* 返回一个vector的迭代器,开始指向索引为0的元素。
*
* 返回的iterator是fail-fast。
*/

public synchronized Iterator<E> iterator() {
return new Itr();
}

Itr的具体实现请往下看。

forEach

@Override
public synchronized void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int elementCount = this.elementCount;
for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}

removeIf

@Override
@SuppressWarnings("unchecked")
public synchronized boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
// figure out which elements are to be removed
// any exception thrown from the filter predicate at this stage
// will leave the collection unmodified
int removeCount = 0;
final int size = elementCount;
final BitSet removeSet = new BitSet(size);
final int expectedModCount = modCount;
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
final E element = (E) elementData[i];
if (filter.test(element)) {
removeSet.set(i);
removeCount++;
}
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}

// shift surviving elements left over the spaces left by removed elements
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
for (int k=newSize; k < size; k++) {
elementData[k] = null; // Let gc do its work
}
elementCount = newSize;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}

return anyToRemove;
}

replaceAll

@Override
@SuppressWarnings("unchecked")
public synchronized void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final int expectedModCount = modCount;
final int size = elementCount;
for (int i=0; modCount == expectedModCount && i < size; i++) {
elementData[i] = operator.apply((E) elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}

sort

@SuppressWarnings("unchecked")
@Override
public synchronized void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, elementCount, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}

spliterator

/**
* Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
* and <em>fail-fast</em> {@link Spliterator} over the elements in this
* list.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
* Overriding implementations should document the reporting of additional
* characteristic values.
*
* @return a {@code Spliterator} over the elements in this list
* @since 1.8
*/

@Override
public Spliterator<E> spliterator() {
return new VectorSpliterator<>(this, null, 0, -1, 0);
}

VectorSpliterator的具体实现请往下看。

内部类

Itr

/**
* An optimized version of AbstractList.Itr
*/

private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;

public boolean hasNext() {
// Racy but within spec, since modifications are checked
// within or after synchronization in next/previous
return cursor != elementCount;
}

public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}

public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
synchronized (Vector.this) {
checkForComodification();
Vector.this.remove(lastRet);
expectedModCount = modCount;
}
cursor = lastRet;
lastRet = -1;
}

@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
synchronized (Vector.this) {
final int size = elementCount;
int i = cursor;
if (i >= size) {
return;
}
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) Vector.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
action.accept(elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}

ListItr

/**
* An optimized version of AbstractList.ListItr
*/

final class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}

public boolean hasPrevious() {
return cursor != 0;
}

public int nextIndex() {
return cursor;
}

public int previousIndex() {
return cursor - 1;
}

public E previous() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
cursor = i;
return elementData(lastRet = i);
}
}

public void set(E e) {
if (lastRet == -1)
throw new IllegalStateException();
synchronized (Vector.this) {
checkForComodification();
Vector.this.set(lastRet, e);
}
}

public void add(E e) {
int i = cursor;
synchronized (Vector.this) {
checkForComodification();
Vector.this.add(i, e);
expectedModCount = modCount;
}
cursor = i + 1;
lastRet = -1;
}
}

VectorSpliterator

/** Similar to ArrayList Spliterator */
static final class VectorSpliterator<E> implements Spliterator<E> {
private final Vector<E> list;
private Object[] array;
private int index; // current index, modified on advance/split
private int fence; // -1 until used; then one past last index
private int expectedModCount; // initialized when fence set

/** Create new spliterator covering the given range */
VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
int expectedModCount) {
this.list = list;
this.array = array;
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}

private int getFence() { // initialize on first use
int hi;
if ((hi = fence) < 0) {
synchronized(list) {
array = list.elementData;
expectedModCount = list.modCount;
hi = fence = list.elementCount;
}
}
return hi;
}

public Spliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null :
new VectorSpliterator<E>(list, array, lo, index = mid,expectedModCount);
}

@SuppressWarnings("unchecked")
public boolean tryAdvance(Consumer<? super E> action) {
int i;
if (action == null)
throw new NullPointerException();
if (getFence() > (i = index)) {
index = i + 1;
action.accept((E)array[i]);
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
}

@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> action) {
int i, hi; // hoist accesses and checks from loop
Vector<E> lst; Object[] a;
if (action == null)
throw new NullPointerException();
if ((lst = list) != null) {
if ((hi = fence) < 0) {
synchronized(lst) {
expectedModCount = lst.modCount;
a = array = lst.elementData;
hi = fence = lst.elementCount;
}
}
else
a = array;
if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
while (i < hi)
action.accept((E) a[i++]);
if (lst.modCount == expectedModCount)
return;
}
}
throw new ConcurrentModificationException();
}

public long estimateSize() {
return (long) (getFence() - index);
}

public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}

用到的设计模式

迭代器模式

详情请参考:Vector与迭代器模式

总结

从源码中,我们不难论证以前对Vector的了解

  • Vector底层是数组。
/**
* 保存vector中元素的数组。vector的容量是数组的长度,数组的长度最小值为vector的元素个数。
*
* 任何在vector最后一个元素之后的数组元素是null。
*
* @serial
*/

protected Object[] elementData;
  • 有序。Vector底层是数组,数组是有序的。
  • 可重复。数组是可重复的。
  • 随机访问效率高,增删效率低。通过索引可以很快的查找到对应元素,而增删元素许多元素的位置都要改变。
  • 线程安全。很多方法都是synchronized的。