Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
Vector 实现Serializable接口,这意味着linkedList支持序列化,能通过序列化去传输。
和ArrayList不同,Vector中的操作是线程安全的。
1.2 Vertor源码public class Vector1.2.2 Vector构造方法 (1). Vector()extends AbstractList implements List , RandomAccess, Cloneable, java.io.Serializable { // 存储元素的数组 protected Object[] elementData; // 数组元素个数 protected int elementCount; // vector需要自动扩容时增加的容量。 //当vector的实际容量elementCount将要大于它的最大容量时,vector自动增加的容量。 // 如果capacityIncrement小于或等于0,vector的容量需要增长时将会成倍增长。 protected int capacityIncrement;
无参构造
构造一个指定容量为10、自增容量为0的空vector。
public Vector() {
// 调用Vector(int initialCapacity)方法
this(10);
}
(2). Vector(Collection extends E> c)
传入一个集合构造Vector
public Vector(Collection extends E> c) {
// 集合转换成数组
Object[] a = c.toArray();
// 获取数组长度
elementCount = a.length;
// 判断C的类型是否为ArrayList类型,如果是的话,直接将a赋值给数组elementData
if (c.getClass() == ArrayList.class) {
elementData = a;
} else {
// 拷贝数组a到一个长度为elementCount的数组
elementData = Arrays.copyOf(a, elementCount, Object[].class);
}
}
(3). Vector(int initialCapacity)
构造一个指定容量为initialCapacity、自增容量为0的空vector。
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
(4). Vector(int initialCapacity, int capacityIncrement)
构造一个指定容量为initialCapacity、自增容量为capacityIncrement的vector。
public Vector(int initialCapacity, int capacityIncrement) {
super();
// 检验自增容量是否小于0,小于0直接抛出异常
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
// 创建一个长度为initialCapacity的数组
this.elementData = new Object[initialCapacity];
// 设置自增容量
this.capacityIncrement = capacityIncrement;
}
1.2.3 Vector增加元素
(1). add(E e)
在数组末尾添加一个元素
添加synchronized修饰方法,代表是线程安全的
public synchronized boolean add(E e) {
// 结构性修改次数自增+1
modCount++;
// 判断是否需要进行扩容
ensureCapacityHelper(elementCount + 1);
// 在数组末尾添加元素
elementData[elementCount++] = e;
return true;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
// 如果至少需要的容量 > 数组缓冲区当前的长度,就进行扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
// 获取数组当前长度
int oldCapacity = elementData.length;
// 扩容
// 如果自增容量大于0,则扩容为oldCapacity+capacityIncrement
// 否则对数组容量进行翻倍扩容
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();
// 如果minCapacity大于MAX_ARRAY_SIZE,则复制为Integer的最大值,否则为MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
(2). add(int index, E element)
在指定索引位置添加一个元素
insertElementAt添加了synchronized修饰符标记
public void add(int index, E element) {
// 调用insertElementAt插入数据
insertElementAt(element, index);
}
public synchronized void insertElementAt(E obj, int index) {
// 结构性修改次数自增+1
modCount++;
// 判断插入的索引位置是否越界
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
// 判断数组是否需要扩容
ensureCapacityHelper(elementCount + 1);
// 将inex及其之后的元素往后挪一位,则index位置处就空出来了
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);、
// 在index索引位置处放入需要插入的元素
elementData[index] = obj;
// 元素长度自增+1
elementCount++;
}
(3). addAll(Collection extends E> c)
添加一个集合
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;
// 返回是否添加成功,当传入的集合长度为0 时返回false代表插入失败
return numNew != 0;
}
(4). addAll(int index, Collection extends E> c)
在指定的索引位置插入一个集合
public synchronized boolean addAll(int index, Collection extends E> c) {
// 结构性修改次数自增+1
modCount++;
// 判断索引是否越界
if (index < 0 || index > elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object[] a = c.toArray();
int numNew = a.length;
// 判断是否需要进行扩容
ensureCapacityHelper(elementCount + numNew);
// 如果index不是最后一位,则将index之后的元素往后挪numNew个位置,将从numMoved的位置空出放入传入的元素
int numMoved = elementCount - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 将c中元素全部拷贝到数组
System.arraycopy(a, 0, elementData, index, numNew);
// 修改数组元素的个数
elementCount += numNew;
// 如果c不为空就返回true,否则返回false
return numNew != 0;
}
(5). addElement(E obj)
添加一个元素
public synchronized void addElement(E obj) {
// 结构性修改次数+1
modCount++;
// 判断是否需要扩容
ensureCapacityHelper(elementCount + 1);
// 在数组末尾出插入元素
elementData[elementCount++] = obj;
}
1.2.4 Vector删除元素
(1). clear()
清空元素
public void clear() {
// 删除所有元素
removeAllElements();
}
public synchronized void removeAllElements() {
modCount++;
// Let gc do its work
// 遍历数组 将数组的值都设置为null,协助GC进行垃圾回收
for (int i = 0; i < elementCount; i++)
elementData[i] = null;
// 将数组的元素个数重置为0
elementCount = 0;
}
(2). remove(int index)
删除指定索引位置元素
public synchronized E remove(int index) {
// 记录结构性改变的次数
modCount++;
// 判断索引是否越界
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
// 如果index不是最后一位,则将index之后的元素往前挪一位
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 将最后一个元素删除,帮助GC
elementData[--elementCount] = null; // Let gc do its work
// 返回删除的旧元素
return oldValue;
}
(3). remove(Object o)
删除一个指定的元素
public boolean remove(Object o) {
// 删除一个元素
return removeElement(o);
}
public synchronized boolean removeElement(Object obj) {
// 结构性修改次数+1
modCount++;
// 查找元素在数组中的索引位置
int i = indexOf(obj);
// 如果在数组中存在,则做进一步的删除操作
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
public synchronized void removeElementAt(int index) {
// 结构性修改次数自增+1
modCount++;
// 判断索引是否越界
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}`
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
// 如果index不是最后一位,则将index之后的元素往前挪一位
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
// 元素个数自减1
elementCount--;
// 将最后一个元素删除,帮助GC
elementData[elementCount] = null;
}
(4). removeAll(Collection> c)
删除指定的元素
public synchronized boolean removeAll(Collection> c) {
// 调用父类AbstractCollection的removeAll方法
return super.removeAll(c);
}
public boolean removeAll(Collection> c) {
// 判断集合是否为空
Objects.requireNonNull(c);
// 创建是否修改的标识
boolean modified = false;
Iterator> it = iterator();
// 循环遍历是否包含集合中的元素,包含的话进行删除
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
(5).removeAllElements()
删除所有元素
public synchronized void removeAllElements() {
modCount++;
// Let gc do its work
// 遍历数组 将数组的值都设置为null,协助GC进行垃圾回收
for (int i = 0; i < elementCount; i++)
elementData[i] = null;
// 将数组的元素个数重置为0
elementCount = 0;
}
1.2.5 Vector修改元素
(1). set(int index, E element)
根据索引修改元素
public synchronized E set(int index, E element) {
// 判断索引是否越界
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
// 获取要被修改的旧元素
E oldValue = elementData(index);
// 将指定索引位置的元素进行替换
elementData[index] = element;
// 返回被修改的元素
return oldValue;
}
// 根据索引获取数据
E elementData(int index) {
return (E) elementData[index];
}
(2). setElementAt(E obj, int index)
根据索引修改元素
public synchronized void setElementAt(E obj, int index) {
// 判断索引是否越界
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
// 根据索引获取数据
elementData[index] = obj;
}
(3). setSize(int newSize)
修改数组大小
public synchronized void setSize(int newSize) {
// 结构性修改次数自增+1
modCount++;
// 传入的新大小大于数组现在的大小,对数组进行扩容
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
// 否则,对于现在数组超过新大小的部分进行清空操作
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
// 修改数组元素个数
elementCount = newSize;
}
1.2.6 Vector查找元素
(1). E get(int index)
public synchronized E get(int index) {
// 判断索引是否越界
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
// 根据索引返回元素
return elementData(index);
}
(2). E firstElement()
获取第一个元素
public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
(3) E lastElement()
获取最后一个元素
public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
(4). int lastIndexOf(Object o)
查找元素最后出现的位置
public synchronized int lastIndexOf(Object o) {
// 从元素末尾开始进行查找
return lastIndexOf(o, elementCount-1);
}
(5). int lastIndexOf(Object o, int index)
从指定的位置,倒序查找元素出现的位置
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;
}
1.3 Vector总结
1、Vector创建时默认大小为10
2、Vector每次扩容但都是以当前数组的2倍扩容,当指定了capacityIncrement后,每次扩容仅在原有基础上增加capacityIncrement个空间(如果指定的空间大小不满足数组增加元素的需求,则依旧是以当前数组的两倍进行扩容)。
3、Vector和ArrayList的add、get、size方法时间复杂度都为 O(1),remove方法的时间复杂度为O(n)
4、ArrayList是线程不安全的,Vector是线程安全的。



