1. Overview
In this tutorial, we’re going to focus on the differences between the ArrayList and Vector classes. They both belong to the Java Collections Framework and implement the java.util.List interface.
However, these classes have significant differences in their implementations.
2. What’s Different?
As a quick start, let’s present the key differences of ArrayList* and *Vector. Then, we’ll discuss some of the points in more detail:
- synchronization – The first major difference between these two. Vector is synchronized and ArrayList isn’t.
- size growth – Another difference between the two is the way they resize while reaching their capacity. The Vector doubles its size. In contrast, ArrayList increases only by half of its length
- iteration – And Vector can use Iterator and Enumeration to traverse over the elements. On the other hand, ArrayList can only use Iterator.
- performance – Largely due to synchronization, Vector operations are slower when compared to ArrayList
- framework – Also, ArrayList is a part of the Collections framework and was introduced in JDK 1.2. Meanwhile, Vector is present in the earlier versions of Java as a legacy class.
3. Vector
As we already have an extended guide about ArrayList, we won’t discuss its API and capabilities here. On the other hand, we’ll present some core details about Vector.
Simply put, a Vector is a resizable array**. It can grow and shrink as we add or remove the elements.
We can create a vector in typical fashion:
Vector<String> vector = new Vector<>();
The default constructor creates an empty Vector with an initial capacity of 10.
Let’s add a few values:
vector.add("baeldung");
vector.add("Vector");
vector.add("example");
And finally, let’s iterate through the values by using the Iterator interface:
Iterator<String> iterator = vector.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
// ...
}
Or, we can traverse the Vector using Enumeration:
Enumeration e = vector.elements();
while(e.hasMoreElements()) {
String element = e.nextElement();
// ...
}
Now, let’s explore some of their unique features in more depth.
4. Concurrency
We’ve already mentioned that ArrayList and Vector are different in their concurrency strategy, but let’s take a closer look. If we were to dive into Vector’s method signatures, we’d see that each has the synchronized keyword:
public synchronized E get(int index)
Simply put, this means that only one thread can access a given vector at a time.
Really, though, this operation-level synchronizations needs to be overlayed anyway with our own synchronization for compound operations.
So in contrast, ArrayList takes a different approach. Its methods are not synchronized and that concern is separated out into classes that are devoted to concurrency.
For example, we can use CopyOnWriteArrayList or Collections.synchronizedList to get a similar effect to Vector:
vector.get(1); // synchronized
Collections.synchronizedList(arrayList).get(1); // also synchronized
5. Performance
As we already discussed above, Vector is synchronized which causes a direct impact on performance.
To see the performance difference between Vector versus ArrayList operations, let’s write a simple JMH benchmark test.
In the past, we’ve looked at the time complexity of ArrayList‘s operations, so let’s add the test cases for Vector.
First, let’s test the get() method:
@Benchmark
public Employee testGet(ArrayListBenchmark.MyState state) {
return state.employeeList.get(state.employeeIndex);
}
@Benchmark
public Employee testVectorGet(ArrayListBenchmark.MyState state) {
return state.employeeVector.get(state.employeeIndex);
}
We’ll configure JMH to use three threads and 10 warmup iterations.
And, let’s report on the average time per operation at the nanosecond level:
Benchmark Mode Cnt Score Error Units
ArrayListBenchmark.testGet avgt 20 9.786 ± 1.358 ns/op
ArrayListBenchmark.testVectorGet avgt 20 37.074 ± 3.469 ns/op
We can see that ArrayList#get works about three times faster than Vector#get.
Now, let’s compare the results of the contains() operation:
@Benchmark
public boolean testContains(ArrayListBenchmark.MyState state) {
return state.employeeList.contains(state.employee);
}
@Benchmark
public boolean testContainsVector(ArrayListBenchmark.MyState state) {
return state.employeeVector.contains(state.employee);
}
And print the results out:
Benchmark Mode Cnt Score Error Units
ArrayListBenchmark.testContains avgt 20 8.665 ± 1.159 ns/op
ArrayListBenchmark.testContainsVector avgt 20 36.513 ± 1.266 ns/op
As we can see, for the contains() operation, the performance time for Vector is much longer than ArrayList.
6. Summary
In this article, we had a look at the differences between the Vector and ArrayList classes in Java. Additionally, we also presented Vector features in more details.
As usual, the complete code for this article is available over on GitHub.