在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。