Vector和前面讲的Arraylist很相似,也是一个保存数据的集合,下面我们来看看Vector的源码。和ArrayList最大区别是,它是一个线程安全的集合,所有方法都加了synchronized,效率相对来说要低一点,另外,有一个增量系数,如果指定,那么每次都会增加一个系数的大小,否则就扩大一倍。

1、重要属性
/**
* 存储元素所使用的数组
*/
protected Object[] elementData;
/**
* 数组中已经存放的元素个数
*/
protected int elementCount;
/**
* 容量增加系数,就是扩容的时候增加的容量
*/
protected int capacityIncrement;
2、构造器
/**
* 带参构造函数
* initialCapacity 初始容量
* capacityIncrement 扩容系数
*/
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 初始容量
*/
public Vector(int initialCapacity) {
// 调用上一个构造函数,扩容系数为0
this(initialCapacity, 0);
}
/**
* 无参构造函数,初始容量默认为10
*/
public Vector() {
this(10);
}
/**
* 将Collection对象转换成数组,然后将数组的地址赋值给elementData。
* 执行Arrays.copy方法,把Collection对象的内容copy到elementData中
*/
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);
}
3、添加元素以及怎么扩容
我们以添加单个元素为例,添加集合或者在指定位置添加元素,大同小异
/**
* e 需要添加进数组的元素
*/
public synchronized boolean add(E e) {
modCount++;
// 扩容 添加第一个元素elementCount 为0
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
/**
* minCapacity 最小容量,添加第一个元素是为1
*/
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
// 当最小容量 - 数组长度 得到的值大于0,就该扩容了,比如:添加到第十一个元素的时候,
// minCapacity = 11,elementData.length = 10,说明数组已经满了,这也说明数组不满的时候,
// 是不会进行扩容的
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 数组最大容量
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 对数组进行扩容
*/
private void grow(int minCapacity) {
// overflow-conscious code
// 旧的数组容量
int oldCapacity = elementData.length;
// 计算新的容量,capacityIncrement 这个值代表每次扩容的时候扩多少,如果初始化的时候传了值,
// 那么就取这个值,如果没传,则取oldCapacity,也就是旧容量的1倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
// 以下两个if是为健壮性考虑,正常情况是不会走进去的
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 将旧数组的内容拷贝到新数组,并将新数组地址赋值给elementData 至此扩容完成
elementData = Arrays.copyOf(elementData, newCapacity);
}
4、删除元素
Vector的批量删除与Arraylist有区别,它是通过迭代器去实现的
/**
* 批量删除
*/
public synchronized boolean removeAll(Collection<?> c) {
// 调用父类的removeAll
return super.removeAll(c);
}
/**
* AbstractCollection的removeAll
*/
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
// iterator会调用到Vector的内部Itr
Iterator<?> it = iterator();
// 通过hasNext判断是否还有下一个元素
// 通过next获取下一个元素,并对cursor、lastRet进行赋值
// 通过contains得到集合是否包含该元素
// 如果包含,则调用迭代器的remove
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
/**
* Vector的内部类Itr的方法,判断集合中是否还有下一个元素
*/
public boolean hasNext() {
// Racy but within spec, since modifications are checked
// within or after synchronization in next/previous
return cursor != elementCount;
}
/**
* Vector的内部类Itr的方法,从集合中获取下一个元素
* cursor 初始值为0 ,每一次调用next(),cursor+1
* 通过cursor、lastRet的转换,获取对应索引下的值
*/
public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}
/**
* Vector的内部类Itr的方法,删除元素
* 因为通过it.next()已经对lastRet进行了赋值,所以真正删除元素的时候调用的是Vector.this.remove(lastRet);
*/
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
synchronized (Vector.this) {
checkForComodification();
Vector.this.remove(lastRet);
expectedModCount = modCount;
}
cursor = lastRet;
lastRet = -1;
}
/**
* Vector的remove方法 最终删除元素的方法
*/
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;
}
4万+

被折叠的 条评论
为什么被折叠?



