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一样,虽然支持同步,但却被抛弃了。