Vectory
第1部分 Vector介绍
Vector简介
Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
和ArrayList不同,Vector中的操作是线程安全的。
Vector的构造函数
Vector共有4个构造函数
// 默认构造函数
Vector()
// capacity是Vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。
Vector(int capacity)
// capacity是Vector的默认容量大小,capacityIncrement是每次Vector容量增加时的增量值。
Vector(int capacity, int capacityIncrement)
// 创建一个包含collection的Vector
Vector(Collection<? extends E> collection)
第2部分 Vector数据结构
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.Vector<E>
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
Vector与Collection关系如下图:
Vector的数据结构和ArrayList差不多,它包含了3个成员变量:elementData , elementCount, capacityIncrement。
(01) elementData 是"Object[]类型的数组",它保存了添加到Vector中的元素
(02) elementCount 是动态数组的实际大小。
(03) capacityIncrement 是动态数组的增长系数。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时>,增加的大小都是capacityIncrement。
第3部分 Vector源码解析
构造函数
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector() {
this(10);
}
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的默认初始容量大小是10(ArrayList为0)
add(E e)
public synchronized boolean add(E e) {
modCount++;
//确保容量足够
ensureCapacityHelper(elementCount + 1);
//添加元素
elementData[elementCount++] = e;
return true;
}
从上面代码可以看到,add()方法用synchronized关键字修饰,所以是线程安全的,ensureCapacityHelper()方法用于确保容量足够,不够时扩展容量,其实现如下:
可以看到,当需要扩容时,将调用grow()方法。
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);
}
可以看到,如果capacityIncrement为0时,那么newCapacity将会是两倍的oldCapacity
其余操作
其余操作与ArrayList类似,只不过每个方法都多了synchronized关键字,从而保证了Vector类的线程安全。
Stack
Stack类的实现比较简单,只是在Vector的基础上添加了一个方法,下面是Stack类的实现:
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
public class Stack<E> extends Vector<E> {
public E push(E item) {
addElement(item);
return item;
}
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() {
int len = size();
if (len == 0)
throw new
EmptyStackException();
return elementAt(len - 1);
}
public boolean empty() {
return size() == 0;
}
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
private static final long serialVersionUID = 1224463164541339165L;
}
从上面的代码可以看到,Stack内部一共五个方法,其中三个方法都加了synchronized关键字,是线程安全的,而push和empty方法调用了Vector的方法,由于Vector中的addElement()和size()方法都是线程安全的,所以Stack的每个方法也都是线程安全的,所以它和Vector一样,都是线程安全的。
总结
Vector与ArrayList的最大区别就是Vector是线程安全的,而ArrayList不是线程安全的。另外区别还有:
- ArrayList不可以设置扩展的容量,默认1.5倍;Vector可以设置扩展的容量,如果没有设置,默认2倍
- ArrayList的无参构造方法中初始容量为0,而Vector的无参构造方法中初始容量为10。
- Vector线程安全,ArrayList线程不安全。
Vector和它的子类Stack都是线程安全的集合。
转载自:https://blog.csdn.net/qq_19431333/article/details/54908404
http://www.cnblogs.com/skywang12345/p/3308833.html