同步
他的实现类似与ArrayList,但是使用了synchronized进行同步
public synchronized boolean add(E e) { modCount++; add(e, elementData, elementCount); return true; } private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); elementData[s] = e; elementCount = s + 1; } public synchronized E get(int index) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData(index); }
扩容
Vector 的构造函数可以传入 capacityIncrement 参数,它的作用是在扩容时使容量 capacity 增长 capacityIncrement。如果这个参数的值小于等于 0,扩容时每次都令 capacity 为原来的两倍
private Object[] grow() { return grow(elementCount + 1); } private Object[] grow(int minCapacity) { int oldCapacity = elementData.length; int newCapacity = ArraysSupport.newLength(oldCapacity, minCapacity - oldCapacity, /* minimum growth */ capacityIncrement > 0 ? capacityIncrement : oldCapacity /* preferred growth */); return elementData = Arrays.copyOf(elementData, newCapacity); }
调用没有 capacityIncrement 的构造函数时,capacityIncrement 值被设置为 0,也就是说默认情况下 Vector 每次扩容时容量都会翻倍。
与ArrayList的比较
- Vector 是同步的,因此开销就比 ArrayList 要大,访问速度更慢。最好使用 ArrayList 而不是 Vector,因为同步操作完全可以由程序员自己来控制;
- Vector 每次扩容请求其大小的 2 倍(也可以通过构造函数设置增长的容量),而 ArrayList 是 1.5 倍。
替代方案
// 可以使用Collections.synchronizedList();,得到一个线程安全的ArrayList List<String> list = new ArrayList<>(); List<String> synlist = Collections.synchronizedList(list); // 也可以使用concurrent并发包下的CopyOnWriteArrayList类 List<String> lsit = new CopyOnWriteArrayList<>();