JDK源代码之Vector

Vector是和HashTable一个时代的容器,拥有支持同步的特点(各个方法前一律加上synchronized关键字)。后来不支持同步的ArrayList替代了Vector,日渐流行,也正是因为这个原因,Vector和ArrayList的内部实现都差不多。

具体的源码我就不一一注释,只放出让我觉得有意思的方法。

Vector默认的容量是10,扩容时加上一个capacityIncrement或直接翻倍。

System.arraycopy与Arrays.copyOf

我在研究源码时,发现Vector里间替地使用以上2个方法,它们究竟有什么差别呢?
翻出Arrays.copyOf的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")

// 利用反射机制创建一个新的数组
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);

// copyOf依旧调用System.arraycopy
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}

可见,copyOf也会调用arraycopy,而且会创建一个新的数组。
而arraycopy会调用系统底层的复制方法,不同系统的arraycop是不同滴。

removeElementAt(int index)与insertElementAt(E obj, int index)

以上2个方法都会调用系统底层的数组复制函数,复杂度都是O(n)。

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 void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;

// GC优化
elementData[elementCount] = null; /* to let gc do its work */
}

// 增加元素
public synchronized void insertElementAt(E obj, int index) {
modCount++;
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
// 调用系统底层的arraycopy
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
elementData[index] = obj;
elementCount++;
}

synchronized

Vector之所以与ArrayList不同,支持同步,完成是多亏了synchronized这个关键字。
Vector和HashTable一样,虽然支持同步,但却被抛弃了。