章
目
录
在Java中,ArrayList和Vector都实现了java.util.List接口,并提供了使用简单的API方法存储和获取对象的能力。然而,在许多方面它们是不同的,我们需要详细了解这两个类,以明智地决定何时使用哪个类。
1.ArrayList与Vector的区别
1.1. 线程安全
Vector是一个同步集合,而ArrayList不是。这意味着在并发应用程序中,我们可以在不需要开发人员使用synchronized关键字进行额外同步控制的情况下使用Vector。Vector内部的公共方法被定义为同步的,这使得Vector中的所有操作都适用于并发需求。
要在并发应用程序中使用ArrayList,我们必须显式控制对实例的线程访问,以使应用程序按预期工作。如果我们希望获取ArrayList的同步版本,那么我们可以使用Collections.synchronizedList()方法。
返回的列表是List接口的内部实现,不同于ArrayList。但它具有与ArrayList类相同的功能。
ArrayList<String> namesList = new ArrayList<>();
namesList.add("alex");
namesList.add("brian");
namesList.add("charles");
namesList.add("david");
//同步 list
List<String> syncNamesList = Collections.synchronizedList(namesList);
syncNamesList.add("edwin");
System.out.println(syncNamesList);
1.2. 容量增加
默认情况下,当Vector需要增加容量以添加元素(当现有容量已满时),Vector在调整大小时将容量增加100%。这意味着向量大小增加为先前容量的两倍。我们可以使用构造函数Vector(int initialCapacity, int capacityIncrement)覆盖默认容量。这里的第二个参数是向量溢出时增加容量的数量。
默认情况下,ArrayList的容量增加50%。在ArrayList中,我们可以定义初始容量,但无法定义容量增量因子。
1.3. 性能
这两个集合都有一个支持数组,用于存储和搜索元素。因此,在添加和获取操作中,实际上没有太大的性能差异。
真正的性能差异是在考虑同步时出现的。
- ArrayList是非同步的,因此在线程安全方面没有时间差。
- 而Vector是同步的,因此在线程管理/锁等方面会有一些开销。
1.4. ConcurrentModificationException
这两个集合在程序修改集合的同时如何处理迭代方面有区别。
ArrayList提供快速失败迭代器。一旦修改ArrayList结构(添加或删除元素),迭代器将抛出ConcurrentModificationException错误。
Vector提供迭代器和枚举。迭代器是快速失败的,但枚举不是。如果在枚举遍历期间修改Vector,它不会失败。
//Vector
Vector<String> vector = new Vector<>(Arrays.asList("A","B","C"));
Enumeration<String> vectorEnums = vector.elements();
while(vectorEnums.hasMoreElements()) {
String value = vectorEnums.nextElement();
if("B".equals(value)) {
vector.add("D");
}
System.out.println(value);
}
System.out.println("================");
//ArrayList
ArrayList<String> list = new ArrayList<>(Arrays.asList("A","B","C"));
Iterator<String> listItr = list.iterator();
while(listItr.hasNext()) {
String value = listItr.next();
if("B".equals(value)) {
list.add("D");
}
System.out.println(value);
}
程序输出:
A
B
C
D
================
A
B
Exception in thread "main"
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.howtodoinjava.ArrayListExample.main(ArrayListExample.java:33)
2.将Vector转换为ArrayList
要将包含对象的Vector转换为包含相似对象的ArrayList,我们可以使用ArrayList构造函数,该构造函数接受另一个集合,并使用Vector的元素初始化ArrayList。
Vector<String> vector = new Vector<>();
vector.add("A");
vector.add("B");
vector.add("C");
vector.add("D");
ArrayList<String> arrayList = new ArrayList<>(vector); //[A, B, C, D]
3.将ArrayList转换为Vector
从ArrayList到Vector的转换与前面的示例非常相似。在这里,我们必须使用Vector构造函数。它接受另一个集合,并使用ArrayList的元素初始化Vector。
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
arrayList.add("D");
Vector<String> vector = new Vector<>(arrayList);
4.结论
在这个简短的Java教程中,我们比较了Vector和ArrayList。请注意,截止到Java 2平台v1.2版本,Vector类已经被修改以实现List接口。如果不需要线程安全的实现,建议使用ArrayList代替Vector。