Java中的Vector与ArrayList区别
在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。