1、api
Vector
类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,
Vector
的大小可以根据需要增大或缩小,以适应创建
Vector
后进行添加或移除项的操作。
每个向量会试图通过维护
capacity
和
capacityIncrement
来优化存储管理。
capacity
始终至少应与向量的大小相等;这个值通常比后者大些,因为随着将组件添加到向量中,其存储将按
capacityIncrement
的大小增加存储块。应用程序可以在插入大量组件前增加向量的容量;这样就减少了增加的重分配的量。
由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是
快速失败的
:如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的 remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就完全失败,而不是冒着在将来不确定的时间任意发生不确定行为的风险。Vector 的 elements 方法返回的 Enumeration
不是
快速失败的。
注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何坚决的保证。快速失败迭代器尽最大努力抛出
ConcurrentModificationException
。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:
迭代器的快速失败行为应该仅用于检测 bug。
从 Java 2 平台 v1.2 开始,此类改进为可以实现
List
接口,使它成为
Java Collections Framework
的成员。与新 collection 实现不同,
Vector
是同步的。
2、源码学习
实现方式和ArrayList非常类似,不同的地方都是一些小细节,比如
在增长内部数组长度时,ArrayList是增加到当前的1.5倍,而Vector允许自定义一个增长基数capacityIncrement,每次都增长capacityIncrement的长度,如果不定义这个值,则每次长度翻倍
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)
;
}
扩大或缩小Vector的长度
public synchronized void
setSize
(
int
newSize) {
modCount
++
;
//
如果是扩大,则调用
ensureCapacityHelper
方法,多余的位全部置位
null
if
(newSize >
elementCount
) {
ensureCapacityHelper(newSize)
;
//
如果是缩小,则在
newSize
以后的位置全部置位
null
}
else
{
for
(
int
i = newSize
;
i <
elementCount
;
i++) {
elementData
[i] =
null;
}
}
//
设置
Vector
的长度为
newSize
elementCount
= newSize
;
}
另外需要注意的是,这个类的线程安全,是建立在几乎所有修改集合操作的方法都加了synchronized关键字,例如:
public synchronized boolean
add
(
E
e) {
modCount
++
;
ensureCapacityHelper(
elementCount
+
1
)
;
elementData
[
elementCount
++] = e
;
return true;
}