Vector
基于 动态数组 实现的线程安全集合
目录
Vector继承关系
Vector实现了Serializable接口,支持序列化,可通过序列化传输
Vector实现了Cloneable接口,覆盖了clone()方法,能被克隆
Vector继承了AbstractList抽象类,实现了集合操作
Vector实现了RandomAccess标记接口,支持快速访问
Vector源码分析
私有 类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() {
// 生动但符合规范, 因为修改被检查在next/previous同步内部或同步之后
return cursor != elementCount;
}
public E next() {
// 使用synchronized来加锁
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;
}
final Object[] es = elementData;
if (i >= es.length)
throw new ConcurrentModificationException();
while (i < size && modCount == expectedModCount)
action.accept(elementAt(es, 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();
}
}
Vector构造函数:
/**
* 构造具有指定初始容量initialCapacity和容量增量capacityIncrement的空Vector
*
* @param initialCapacity the initial capacity of the vector
* @param capacityIncrement the amount by which the capacity is
* increased when the vector overflows
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
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的空Vector
*
* @param initialCapacity the initial capacity of the vector
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
/**
* 构造一个内部数据数组的大小=10且容量增量=0的空Vector
*/
public Vector() {
this(10);
}
/**
* 构造一个Vector, 包含指定集合的元素, 按集合迭代器返回元素顺序排列
*
* @param c the collection whose elements are to be placed into this
* vector
* @throws NullPointerException if the specified collection is null
* @since 1.2
*/
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
Vector容量方法:
/**
* 将此Vector的元素复制到指定的数组中
*
* @param anArray the array into which the components get copied
* @throws NullPointerException if the given array is null
* @throws IndexOutOfBoundsException if the specified array is not
* large enough to hold all the components of this vector
* @throws ArrayStoreException if a component of this vector is not of
* a runtime type that can be stored in the specified array
* @see #toArray(Object[])
*/
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
/**
* 将该Vector的最大容量变为该Vector的当前大小
* 如果该Vector的容量大于其当前大小, 则通过将其内部数据数组elementData替换为一个等于大小的容量
* 应用程序可以使用此操作最小化等于大小的存储
*/
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
/**
* 增加Vector容量, 以确保它至少可以容纳由最小容量参数指定的组件数量
*
* @param minCapacity the desired minimum capacity
*/
public synchronized void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
modCount++;
if (minCapacity > elementData.length)
grow(minCapacity);
}
}
/**
* 增加容量以确保它至少可以容纳由minCapacity指定的元素数量
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
private Object[] grow() {
return grow(elementCount + 1);
}
/**
* 返回至少与给定的最小容量相同大的容量
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private int newCapacity(int minCapacity) {
int oldCapacity = elementData.length;
// 若 增量capacityIncrement > 0
// 则新容量 = 旧容量 + 增量
// 否则 新容量 = 旧容量 * 2
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity <= 0) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE : // 所需最小容量 > MAX_ARRAY_SIZE, 则返回整形Integer最大值
MAX_ARRAY_SIZE;
}
/**
* 设置Vector的大小
* 若新Size > 当前Size, 以null填充
* 若新Size < 当前Size, 后续元素丢弃
*
* @param newSize the new size of this vector
* @throws ArrayIndexOutOfBoundsException if the new size is negative
*/
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementData.length)
grow(newSize);
final Object[] es = elementData;
for (int to = elementCount, i = newSize; i < to; i++)
es[i] = null;
elementCount = newSize;
}
Vector增删方法:
/**
* 返回Vector的元素的Enumeration
* 返回的Enumeration将生成此Vector中的所有项
* 如果在对元素进行枚举时对向量进行了结构修改, 则枚举的结果是未定义的
*
* @return an enumeration of the components of this vector
* @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");
}
};
}
/**
* 将此Vector的指定索引处的元素设置为指定对象
* 索引的值必须大于或等于0, 且小于Vector的当前大小
*
* 该方法在功能上与set(int, Object) set(int, E)方法(List接口的一部分)相同
* 注意:set方法颠倒了参数的顺序, 以便更接近于匹配数组的使用, set方法返回存储在指定位置的旧值
*
* @param obj what the component is to be set to
* @param index the specified index
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}
/**
* Deletes the component at the specified index. Each component in
* this vector with an index greater or equal to the specified
* {@code index} is shifted downward to have an index one
* smaller than the value it had previously. The size of this vector
* is decreased by {@code 1}.
*
* <p>The index must be a value greater than or equal to {@code 0}
* and less than the current size of the vector.
*
* <p>This method is identical in functionality to the {@link #remove(int)}
* method (which is part of the {@link List} interface). Note that the
* {@code remove} method returns the old value that was stored at the
* specified position.
*
* @param index the index of the object to remove
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
*/
public synchronized void removeElementAt(int index) {
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);
}
modCount++;
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
/**
* 将指定的对象作为元素插入到指定的索引中
*
* 索引的值必须>= 0, 且<= >Vector当前大小
*
* @param obj the component to insert
* @param index where to insert the new component
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index > size()})
*/
public synchronized void insertElementAt(E obj, int index) {
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
modCount++;
final int s = elementCount;
Object[] elementData = this.elementData;
if (s == elementData.length)
elementData = grow(); // 扩容
System.arraycopy(elementData, index,
elementData, index + 1,
s - index); // 将index到end元素复制,变为index+1到end, 空出index位置
elementData[index] = obj;
elementCount = s + 1;
}
/**
* 这个帮助器方法从add(E)中分离出来
* 将方法字节码大小保持在35以下(-XX:MaxInlineSize默认值)
* 这有助于在c1编译的循环中调用add(E)
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
elementCount = s + 1;
}
/**
* 将指定的元素附加到此向量的末尾
*
* @param e element to be appended to this Vector
* @return {@code true} (as specified by {@link Collection#add})
* @since 1.2
*/
public synchronized boolean add(E e) {
modCount++;
add(e, elementData, elementCount);
return true;
}
/**
* 移除此向量中指定位置的元素
* 将任何后续元素向左移动
*
* @param index the index of the element to be removed
* @return element that was removed
* @throws ArrayIndexOutOfBoundsException if the index is out of range
* ({@code index < 0 || index >= size()})
* @since 1.2
*/
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index); // 获取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;
}
/**
* 将指定集合中的所有元素按照指定集合的迭代器返回它们的顺序追加到此Vextor的末尾
*
* @param c elements to be inserted into this Vector
* @return {@code true} if this Vector changed as a result of the call
* @throws NullPointerException if the specified collection is null
* @since 1.2
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
modCount++;
int numNew = a.length;
if (numNew == 0)
return false;
synchronized (this) {
Object[] elementData = this.elementData;
final int s = elementCount;
if (numNew > elementData.length - s)
elementData = grow(s + numNew);
System.arraycopy(a, 0, elementData, s, numNew);
elementCount = s + numNew;
return true;
}
}
Vector总结
Vector基于数组和链表实现的存储结构
Vector是线程安全的,使用synchronized关键字
Vector性能比HashMap低,且不允许插入null元素
Vector的初始容量=11,负载因子=0.75
Vector每次扩容,新容量=旧容量 * 2 + 1