Arraylist与Vector的区别

       Arraylist与Vector的区别是什么?

  1. Vector是线程安全的,ArrayList不是线程安全的。
  2. ArrayList在底层数组不够用时在原来的基础上扩展0.5倍,Vector是扩展1倍。

       Vector和ArrayList一样,都继承自List,来看一下Vector的源码:

1
2
3
4
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
protected Object[] elementData;
...
}

       实现了List接口,底层和ArrayList一样,都是数组来实现的。分别看一下这两个类的add方法,首先来看ArrayList的add源码:

1
2
3
4
5
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!! 检查底层数组是否需要扩容
elementData[size++] = e;//给底层数组元素赋值
return true;
}

       再看Vector的add源码:

1
2
3
4
5
6
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);//检查底层数组是否需要扩容
elementData[elementCount++] = e;//给底层数组元素赋值
return true;
}

       方法实现都一样,就是加了一个synchronized的关键字,再来看看其它方法,先看ArrayList的remove方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public E remove(int index) {
rangeCheck(index);

modCount++;
E oldValue = elementData(index);

int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work

return oldValue;
}

       再看Vector的remove方法:

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

       方法实现上也一样,就是多了一个synchronized关键字,再看看ArrayList的get方法:

1
2
3
4
5
public E get(int index) {
rangeCheck(index);

return elementData(index);
}

       Vector的get方法:

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

return elementData(index);
}

       再看看Vector的其它方法:

1
2
3
4
5
6
7
8
9
10
11
public synchronized int capacity() {
return elementData.length;
}

public synchronized int size() {
return elementCount;
}

public synchronized boolean isEmpty() {
return elementCount == 0;
}

       无一例外,只要是关键性的操作,方法前面都加了synchronized关键字,来保证线程的安全性。当执行synchronized修饰的方法前,系统会对该方法加一把锁,方法执行完成后释放锁,加锁和释放锁的这个过程,在系统中是有开销的,因此,在单线程的环境中,Vector效率要差很多。(多线程环境不允许用ArrayList,需要做处理)。

       和ArrayList和Vector一样,同样的类似关系的类还有HashMap和HashTable、StringBuilder和StringBuffer、后者是前者线程安全版本的实现。

参考资料:
清浅池塘 Arraylist与Vector的区别

Fork me on GitHub