Vector和ArrayList这两个集合类的本质并没有太大的不同,它们都实现了List接口,而且底层都是基于Java数组来存储集合元素。
在ArrayList集合类的源代码中可以看到如下一行。
- 1
- 2
- 1
- 2
在Vector集合类的源代码中也可看到类似的一行。
- 1
- 2
- 1
- 2
从上面代码可以看出,ArrayList使用 transient
修饰了 elementData 数组。这保证系统序列化ArrayList对象时不会直接序列号elementData数组,而是通过ArrayList提高的writeObject、readObject方法来实现定制序列化;但对于Vector而言,它没有使用transient修饰elementData数组,而且Vector只提供了一个writeObject方法,并未完全实现定制序列化。
从序列化机制的角度来看,ArrayList的实现比Vector的实现更安全。除此之外,Vector其实就是ArrayList的线程安全版本
,ArrayList和Vector绝大部分方法的实现都是相同的,只是Vector的方法增加了 synchronized
修饰。
下面先来看ArrayList中的add(int index, E element)方法的源代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
再来看Vector中add(int index, E element)方法的源代码,如下所示。
- 1
- 2
- 3
- 1
- 2
- 3
从上面代码可以看出:Vector的add(int index, E element)方法其实就是insertElementAt(element, index)方法。下面是insertElementAt(element, index) 方法的源代码。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
将ArrayList中的add(int index, E element)方法和Vector的insertElementAt(E obj, int index)方法进行对比,可以发现Vector的方法只是多了synchronized修饰,而且多了①行代码。这并不代表ArrayList的add(int index, E element)方法就没有这行代码,ArrayList只是将这行代码放在ensureCapacity(size + 1)中完成。
ArrayList中使用size实例变量来保存集合中元素的个数,而Vector中使用elementCount实例变量来保存集合元素的个数。两个变量的作用没有任何区别,只是size变量名更简洁。
下面是ArrayList的ensureCapacity(int minCapacity)方法的源代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
类似地,Vector提供了ensureCapacityHelper(int minCapacity)方法来完成类似地功能,如下所示。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
将ArrayList中的ensureCapacity(int minCapacity)方法和Vector的ensureCapacityHelper(int minCapacity)方法进行对比,可以发现这两个方法几乎完全相同,只是在扩充底层数组的容量时略有区别而已。ArrayList总是将底层容量扩充为原来的1.5倍,但Vector则多了一个选择:当capacityIncrement实例变量大于0时,扩充后的容量等于原来的容量加上capacityIncrement的值
。
Vector的ensureCapacityHelper(int minCapacity)方法在扩充底层数组容量时多一个选择是因为,创建Vector可以传入一个capacityIncrement参数,如下构造器所示。
- 1
- 1
以initialCapacity作为底层数组的初始长度,以capacityIncrement作为数组长度扩充时的增大步长来创建Vector对象。但对于ArrayList而言,它的构造器最多只能指定一个initialCapacity参数。
总结:
- ArrayList和Vector都实现了List接口,底层都是基于Java数组来存储集合元素
- ArrayList使用transient修饰了elementData数组,而Vector则没有
- Vector是ArrayList的线程安全版本
- 容量扩充 ArrayList为0.5倍+1,而Vector若指定了增长系数,则新的容量=”原始容量+增长系数”, 否则增长为原来的1倍