此Vector非彼Vector
2004-08-05 15:51 FantasySoft 阅读(3252) 评论(2) 编辑 收藏 举报 在学习STL的过程中,我发现了一个熟悉的面孔——Vector。之所以熟悉,是因为Vector是Java核心类库中的Collection container的一种,然而在我近一年的开发历程当中,我从来都没有使用过Vector,甚至对其几乎是一无所知,只是知道这是JDK中遗留的Collection container,而且在开发过程中也不提倡使用它。花心的我在看着STL的Vector的时候,心里还是惦记着我那可爱的Java情人[1]。于是,我翻出了JDK的document,翻出了Vector的source code,去看个究竟。
噢,Vector原来就是动态数组啊,这不是跟STL中的Vector很类似吗?即使在Java核心类库当中,ArrayList不也是动态数组吗?而STL并没有跟ArrayList相match的东东啊(至少看字面上就没有)。那么在Java中Vector与ArrayList有什么区别呢?那么Java中的Vector与STL中Vector呢?
在Java当中,Vector与ArrayList都是AbstractList派生的子类,在很多方面它们是很类似的:
1、实现了动态增长的数组;
2、通过对象数组(Object[])来实现数据的存储,因此它们都无法容纳原始类型(primitive type),如 int类型的数据;
而它们的区别:
1、正如JDK上所说的那样(This class is roughly equivalent to Vector, except that it is unsynchronized),主要在同步性上:Vector是同步的,而ArrayList是非同步的。由于实现同步,在效率上Vector要比ArrayList要低。
2、除此之外,它们在数组的动态增长的策略上也是不同。往Vector增加一个元素的时候,如果Vector的容量(capacity)不足的时候,将会从新创建一个对象数组,请看下面来自 JDK的源代码:
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (capacityIncrement > 0) ?
(oldCapacity + capacityIncrement) : (oldCapacity * 2);
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, elementCount);
}
}
这里得特别说一下,如果使用不带参数的构造函数( Vector() )去创建一个Vector实例的话,capacityIncrement的初始值为0,而capacity为10。
而ArrayList在遇到capacity不足的时候,所创建的对象数组的capacity为newCapacity = (oldCapacity * 3)/2 + 1。我不赞同一些人所说的保存大量数据时候,就应该使用Vector。诚然,由于Vector采取的数组动态增长的策略,使得新创建的对象数组相对较大,减少了分配内存和数组拷贝的次数,但是这样带来的副作用是造成了内存空间的浪费;同时,我觉得应该尽可能少用不带参数的构造方法,在构造实例的同时为Vector或者ArrayList赋予合适的capacity才是最好的解决办法。
3、Vector提供了比ArrayList丰富得多的函数。如Vector提供了
修改某个索引值对应元素的方法:setElementAt(Object, int);
在某个索引值前插入元素的方法:insertElementAt(Object,int);
返回capacity的方法:capacity();
……
相比之下,也许是因为同步造成的问题吧,否则我怎么都想不明白为什么不提倡使用Vector。同时,在比较ArrayList和Vector过程中,我也越发觉得泛型的强大了,最明显的就是ArrayList和Vector都使用对象数组去存储数据,编译器就无法对其进行类型检查了。至于STL中的Vector与Java中的Vector有什么区别,下次再续了。
[1] Summary of function parameter