Vector源码解析

Vector和ArrayList非常相似,它们都实现了相同的接口,继承相同的类,就连方法的实现也非常类似。和ArrayList不同的是,Vector是线程安全的,关键方法上都加了synchronized同步锁,由于Vector效率不高,所以使用的较少,要使用线程安全的ArrayList,推荐CopyOnWriteArrayList,后续再做分析,这里仅记录下Vector源码,基于JDK1.8。

类结构

Vector的类关系图和ArrayList一致:

QQ20210220-163414@2x

Vector可以存放任意类型元素(包括null),允许重复,和ArrayList一致,内部采用Object类型数组存放数据,包含以下三个成员变量:

1
2
3
4
5
6
7
8
// Object数组,存放数据
protected Object[] elementData;

// 元素个数
protected int elementCount;

// 当数组容量不足时,容量增加capacityIncrement,如果capacityIncrement为0,则扩容为2倍
protected int capacityIncrement;

方法解析

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
}

可以看到,当我们调用new Vector()创建Vector集合时,直接创建了一个容量为10的Object数组(和ArrayList不同,ArrayList内部数组初始容量为0,只有在添加第一个元素的时候才扩容为10),并且capacityIncrement为0,意味着容量不足时,新数组容量为旧数组容量的2倍。

add(E e)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public synchronized boolean add(E e) {
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;
// capacityIncrement为0的话,新容量为旧容量的2倍,不为0,则新容量为旧容量+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) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}

添加逻辑和ArrayList的add方法大体一致,区别在于扩容策略有些不同,并且方法使用synchronized关键字修饰。

set(int index, E element)

1
2
3
4
5
6
7
8
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);

E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}

逻辑和ArrayList的set方法一致,方法使用synchronized关键字修饰。

get(int index)

1
2
3
4
5
6
7
8
9
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);

return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}

逻辑和ArrayList的get方法一致,方法使用synchronized关键字修饰。

remove(int index)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}

逻辑和ArrayList的remove方法一致,方法使用synchronized关键字修饰。

trimToSize()

1
2
3
4
5
6
7
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}

逻辑和ArrayList的trimToSize方法一致,方法使用synchronized关键字修饰。

剩下的方法源码自己查看,大体和ArrayList没有什么区别。Vector的方法都用synchronized关键字来确保线程安全,每次只有一个线程能访问此对象,在线程竞争激烈的情况下,这种方法效率非常低,所以实际并不推荐使用Vector。

请作者喝瓶肥宅水🥤

0