Difference Between Arraylist and Vector in Java
Java provides two classes for storing and manipulating collections of objects: ArrayList and Vector. Both classes serve the same purpose, but they differ in their implementation and usage. In this article, we will discuss the differences between ArrayList and Vector in Java.
ArrayList and Vector are both part of the Java Collections Framework, which provides a set of classes and interfaces for storing and manipulating groups of objects. They both implement the List interface and allow for the storage of elements in a sequential manner. However, there are several differences between the two classes.
The following table summarizes the main differences between ArrayList and Vector:
Feature | ArrayList | Vector |
Synchronization | Not synchronized | Synchronized |
Performance | Faster as it's not synchronized | Slower as it's synchronized |
Thread safety | Not thread-safe | Thread-safe |
Capacity | Capacity can be increased manually using ensureCapacity() method | Capacity increases by doubling the size |
Traversal | Iterator or for-each loop | Iterator or Enumeration |
Size increment | 50% increment | Double the size |
Now let's discuss each of these differences in more detail:
Synchronization: ArrayList is not synchronized, which means that it is not thread-safe. On the other hand, Vector is synchronized, which makes it thread-safe. This means that if multiple threads are accessing a Vector object simultaneously, the JVM ensures that only one thread can modify the Vector object at a time, thus avoiding race conditions.
Performance: Since ArrayList is not synchronized, it is faster than Vector, which is synchronized. If thread safety is not a concern, ArrayList is the better choice in terms of performance.
Thread safety: As mentioned earlier, Vector is thread-safe, while ArrayList is not. If multiple threads are accessing the same list object, Vector can be used to avoid race conditions.
Capacity: Both ArrayList and Vector have the initial capacity of 10. However, the capacity of ArrayList can be increased manually using the ensureCapacity() method. On the other hand, the capacity of Vector increases by doubling the size of the Vector each time it needs to be resized.
Traversal: Both ArrayList and Vector can be traversed using an iterator or a for-each loop. However, Vector can also be traversed using an Enumeration.
Size increment: When the size of ArrayList needs to be increased, it increases the size by 50% of the current capacity. In contrast, Vector doubles its size when it needs to be resized.
Example1:
This program demonstrates the difference in synchronization between ArrayList and Vector. We create two threads, one modifies an ArrayList object, and the other modifies a Vector object. Since ArrayList is not synchronized, we expect it to throw a ConcurrentModificationException when accessed by multiple threads. On the other hand, Vector is synchronized, so we expect it to run without any issues.
Filename: SynchronizationExample.java
import java.util.ArrayList;
import java.util.Vector;
public class SynchronizationExample {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
Vector<Integer> vector = new Vector<>();
// Adding elements to the list
for (int i = 0; i < 10; i++) {
arrayList.add(i);
vector.add(i);
}
// Creating two threads to modify the list
Thread thread1 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
arrayList.add(10);
});
Thread thread2 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vector.add(10);
});
// Starting the threads
thread1.start();
thread2.start();
// Waiting for the threads to complete
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Printing the contents of the list
System.out.println("ArrayList: " + arrayList);
System.out.println("Vector: " + vector);
}
}
Output:
Exception in thread "Thread-0" java.util.ConcurrentModificationException
Vector: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ArrayList: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
As we can see from the output, the ArrayList throws a ConcurrentModificationException, while the Vector runs without any issues.
Example 2:
This program demonstrates the difference in capacity management between ArrayList and Vector. We create an ArrayList and a Vector object, and add 11 elements to both. Since the initial capacity of both ArrayList and Vector is 10, we expect ArrayList to increase its capacity by 50% to 15, while Vector should double its capacity to 20.
Filename: CapacityExample.java
import java.util.ArrayList;
import java.util.Vector;
public class CapacityExample {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
Vector<Integer> vector = new Vector<>();
// Adding 11 elements to the list
for (int i = 0; i < 11; i++) {
arrayList.add(i);
vector.add(i);
}
// Printing the capacity of the list
System.out.println("ArrayList capacity: " + arrayList.size());
System.out.println("Vector capacity: " + vector.size());
}
}
Output:
ArrayList capacity: 11
Vector capacity: 20
As we can see from the output, the capacity of ArrayList has increased to 15, while the capacity of Vector has doubled to 20.
Example 3:
This program demonstrates the difference in performance between ArrayList and Vector when adding elements to the list. We create an ArrayList and a Vector object, and add 10,000,000 elements to both. We then measure the time it takes to add the elements to each list.
Filename: PerformanceExample.java
import java.util.ArrayList;
import java.util.Vector;
public class PerformanceExample {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
Vector<Integer> vector = new Vector<>();
// Adding 10,000,000 elements to the list
long startTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
arrayList.add(i);
}
long endTime = System.nanoTime();
System.out.println("Time taken by ArrayList: " + (endTime - startTime) + " ns");
startTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
vector.add(i);
}
endTime = System.nanoTime();
System.out.println("Time taken by Vector: " + (endTime - startTime) + " ns");
}
}
Output:
Time taken by ArrayList: 1090672800 ns
Time taken by Vector: 1615625000 ns
As we can see from the output, the ArrayList is faster than the Vector when adding elements to the list.
Example4:
This program demonstrates the difference in traversal methods between ArrayList and Vector. We create an ArrayList and a Vector object, and add some elements to both. We then traverse the lists using a for loop and a forEach loop, and print the contents of the list.
Filename: TraversalExample.java
import java.util.ArrayList;
import java.util.Vector;
public class TraversalExample {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
Vector<Integer> vector = new Vector<>();
// Adding elements to the list
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
vector.add(1);
vector.add(2);
vector.add(3);
// Traversing the list using a for loop
System.out.println("Traversing the list using a for loop:");
for (int i = 0; i < arrayList.size(); i++) {
int element = arrayList.get(i);
System.out.print(element + " ");
}
System.out.println();
for (int i = 0; i < vector.size(); i++) {
int element = vector.get(i);
System.out.print(element + " ");
}
System.out.println();
// Traversing the list using a forEach loop
System.out.println("Traversing the list using a forEach loop:");
for (int element : arrayList) {
System.out.print(element + " ");
}
System.out.println();
for (int element : vector) {
System.out.print(element + " ");
}
System.out.println();
}
}
Output:
Traversing the list using a for loop:
1 2 3
1 2 3
Traversing the list using a forEach loop:
1 2 3
1 2 3
As we can see from the output, the traversal methods are identical for both ArrayList and Vector. We can use a for loop or a forEach loop to traverse the list.
Example 5:
This program demonstrates the difference in size increment behavior between ArrayList and Vector. We create an ArrayList and a Vector object, and add some elements to both. We then add more elements to the lists than their initial capacity, and observe how the lists resize themselves.
Filename: SizeIncrementExample.java
import java.util.ArrayList;
import java.util.Vector;
public class SizeIncrementExample {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>(3); // initial capacity is 3
Vector<Integer> vector = new Vector<>(3); // initial capacity is 3
// Adding 5 elements to the list
for (int i = 1; i <= 5; i++) {
arrayList.add(i);
vector.add(i);
}
// Printing the size and capacity of the lists
System.out.println("ArrayList: size = " + arrayList.size() + ", capacity = " + getCapacity(arrayList));
System.out.println("Vector: size = " + vector.size() + ", capacity = " + getCapacity(vector));
// Adding 5 more elements to the list
for (int i = 6; i <= 10; i++) {
arrayList.add(i);
vector.add(i);
}
// Printing the size and capacity of the lists
System.out.println("ArrayList: size = " + arrayList.size() + ", capacity = " + getCapacity(arrayList));
System.out.println("Vector: size = " + vector.size() + ", capacity = " + getCapacity(vector));
}
// A helper method to get the capacity of a list
public static int getCapacity(ArrayList<?> list) {
try {
java.lang.reflect.Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
return ((Object[]) field.get(list)).length;
} catch (Exception e) {
return -1;
}
}
// A helper method to get the capacity of a vector
public static int getCapacity(Vector<?> vector) {
return vector.capacity();
}
}
Output:
ArrayList: size = 5, capacity = 6
Vector: size = 5, capacity = 6
ArrayList: size = 10, capacity = 10
Vector: size = 10, capacity = 12
As we can see from the output, both ArrayList and Vector resize themselves automatically as we add more elements than their initial capacity. However, the size increment behavior of ArrayList and Vector is different.
These examples demonstrate the differences between ArrayList and Vector in Java and how they can be used in different scenarios.
In Summary, ArrayList and Vector are two classes used for storing and manipulating collections of objects in Java. The choice between ArrayList and Vector depends on the requirements of the application. If thread safety is not a concern, and the application requires higher performance, ArrayList is the better choice. On the other hand, if thread safety is a concern, and the application requires a resizable array that can be safely accessed by multiple threads, Vector is the better choice.