Vector Class in Java – Complete Guide with Examples
Vector is a growable array of objects in the java.util package. It has been in Java since JDK 1.0, before the Collections Framework existed, and was later updated to implement the List interface. Its defining feature is that every public method is synchronized, so only one thread can use a Vector at a time.
You will still meet Vector in older code and in interviews, so it is worth knowing well. In this tutorial you will learn its methods, how its capacity grows, how it differs from ArrayList, and what to use instead in new code.
1. What Is a Vector?
A Vector works almost exactly like an ArrayList: it stores elements in an internal array that grows when it is full. The differences come from its age and its built-in locking.
- Resizable array: fast access by index, like ArrayList.
- Ordered, with duplicates and
nullallowed. - Synchronized: each method locks the whole Vector, which makes single calls thread-safe but slower.
- Doubles when full by default (ArrayList grows by about 50%), or grows by a fixed step you choose.
- Default capacity of 10.
- Legacy extras: old method names such as
addElement()andelementAt(), and theEnumerationinterface. - Fail-fast iterators: the
IteratorandListIteratorthrowConcurrentModificationExceptionif the Vector is changed structurally during iteration.
2. Class Hierarchy and Declaration
Vector extends AbstractList and implements List, RandomAccess, Cloneable and Serializable, exactly like ArrayList. The legacy Stack class extends Vector.
public class Vector<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
3. Your First Vector Program
Because Vector implements List, you use it with the same methods as any list. Unlike ArrayList, it also lets you read its current capacity().
import java.util.Vector;
public class VectorQuickStart {
public static void main(String[] args) {
Vector<String> colors = new Vector<>();
colors.add("Red");
colors.add("Green");
colors.add(1, "Blue"); // insert at index 1
System.out.println("Vector: " + colors);
System.out.println("get(0): " + colors.get(0));
System.out.println("size: " + colors.size());
System.out.println("capacity: " + colors.capacity());
colors.remove("Green");
System.out.println("After remove: " + colors);
}
}
Vector: [Red, Blue, Green] get(0): Red size: 3 capacity: 10 After remove: [Red, Blue]
4. Constructors
| Constructor | What it does |
|---|---|
Vector() | Empty Vector with capacity 10 that doubles when full. |
Vector(int initialCapacity) | Empty Vector with the given capacity; doubles when full. |
Vector(int initialCapacity, int capacityIncrement) | Empty Vector that grows by capacityIncrement each time it is full. An increment of 0 or less means "double". |
Vector(Collection<? extends E> c) | Vector containing the elements of another collection. |
5. How Capacity Grows
When a Vector is full, it creates a bigger array and copies the elements into it. By default the new array is twice as large. If you pass a capacityIncrement, it grows by exactly that amount instead. The program below prints the capacity every time it changes.
import java.util.Vector;
public class VectorCapacity {
public static void main(String[] args) {
// Default: capacity 10, doubles when full
Vector<Integer> doubling = new Vector<>();
System.out.print("Default growth: ");
int last = -1;
for (int i = 0; i < 50; i++) {
doubling.add(i);
if (doubling.capacity() != last) {
last = doubling.capacity();
System.out.print(last + " ");
}
}
System.out.println();
// Fixed increment: capacity 4, grows by 3 each time
Vector<Integer> stepped = new Vector<>(4, 3);
System.out.print("Increment of 3: ");
last = -1;
for (int i = 0; i < 15; i++) {
stepped.add(i);
if (stepped.capacity() != last) {
last = stepped.capacity();
System.out.print(last + " ");
}
}
System.out.println();
stepped.trimToSize();
System.out.println("After trimToSize: size=" + stepped.size() + ", capacity=" + stepped.capacity());
}
}
Default growth: 10 20 40 80 Increment of 3: 4 7 10 13 16 After trimToSize: size=15, capacity=15
Doubling means fewer copies but can waste memory: a Vector holding 81 elements reserves space for 160. trimToSize() releases the unused space.
6. Legacy Methods
Vector keeps the method names it had in JDK 1.0. They still work and appear in older code, but the standard List methods are clearer and work with every list type.
import java.util.Vector;
public class VectorLegacyMethods {
public static void main(String[] args) {
Vector<String> days = new Vector<>();
// Legacy methods from JDK 1.0 (still work, but prefer the List methods)
days.addElement("Mon");
days.addElement("Wed");
days.insertElementAt("Tue", 1);
System.out.println("Vector: " + days);
System.out.println("firstElement(): " + days.firstElement());
System.out.println("lastElement(): " + days.lastElement());
System.out.println("elementAt(1): " + days.elementAt(1));
days.setElementAt("Wednesday", 2);
days.removeElement("Mon");
System.out.println("After changes: " + days);
days.setSize(4); // pads with null
System.out.println("After setSize(4): " + days);
}
}
Vector: [Mon, Tue, Wed] firstElement(): Mon lastElement(): Wed elementAt(1): Tue After changes: [Tue, Wednesday] After setSize(4): [Tue, Wednesday, null, null]
| Legacy method | Modern List equivalent |
|---|---|
addElement(e) | add(e) |
insertElementAt(e, i) | add(i, e) |
elementAt(i) | get(i) |
setElementAt(e, i) | set(i, e) (note the reversed arguments) |
removeElement(o) | remove(o) |
removeElementAt(i) | remove(i) |
removeAllElements() | clear() |
firstElement(), lastElement() | getFirst(), getLast() (Java 21+) |
elements() | iterator() |
7. Enumeration vs Iterator
Enumeration is the original JDK 1.0 way to walk through a Vector. It can only read. Iterator, added in JDK 1.2, has shorter method names and a remove() method.
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class VectorEnumeration {
public static void main(String[] args) {
Vector<String> cities = new Vector<>();
cities.add("Agra");
cities.add("Bhopal");
cities.add("Chennai");
// Old style: Enumeration (read-only, no remove())
Enumeration<String> en = cities.elements();
while (en.hasMoreElements()) {
System.out.print(en.nextElement() + " ");
}
System.out.println();
// Modern style: Iterator (can remove safely)
Iterator<String> it = cities.iterator();
while (it.hasNext()) {
if (it.next().startsWith("B")) it.remove();
}
System.out.println("After Iterator.remove(): " + cities);
}
}
Agra Bhopal Chennai After Iterator.remove(): [Agra, Chennai]
| Feature | Enumeration | Iterator |
|---|---|---|
| Introduced in | JDK 1.0 | JDK 1.2 |
| Methods | hasMoreElements(), nextElement() | hasNext(), next(), remove() |
| Can remove elements | No | Yes |
| Fail-fast | No | Yes |
| Works with | Legacy classes (Vector, Hashtable) | All collections |
8. Vector and Thread Safety
Every Vector method is synchronized, so two threads can safely call add() at the same time and no update is lost. However, a sequence of calls is not atomic. "Check that the Vector is not empty, then remove the last element" can still fail if another thread empties it between the two calls. For such compound actions you must lock the Vector yourself.
import java.util.Vector;
public class VectorThreads {
public static void main(String[] args) throws InterruptedException {
Vector<Integer> shared = new Vector<>();
Runnable writer = () -> {
for (int i = 0; i < 10_000; i++) {
shared.add(i); // each call is synchronized
}
};
Thread t1 = new Thread(writer);
Thread t2 = new Thread(writer);
t1.start(); t2.start();
t1.join(); t2.join();
System.out.println("Size after two threads: " + shared.size());
// A check followed by an action is NOT atomic: lock the vector yourself
synchronized (shared) {
if (!shared.isEmpty()) {
shared.remove(shared.size() - 1);
}
}
System.out.println("Size after safe remove: " + shared.size());
}
}
Size after two threads: 20000 Size after safe remove: 19999
Iterating also needs a manual lock: hold synchronized (vector) for the whole loop, otherwise another thread can change the Vector and cause a ConcurrentModificationException.
9. The Stack Class
java.util.Stack extends Vector and adds push(), pop(), peek(), empty() and search(). Because it inherits from Vector, it is synchronized and also exposes list methods such as add(index, e), which break the idea of a stack. The Java documentation recommends ArrayDeque instead.
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
// Legacy Stack (extends Vector)
Stack<String> undo = new Stack<>();
undo.push("type A");
undo.push("type B");
undo.push("delete");
System.out.println("Stack: " + undo + ", pop() -> " + undo.pop() + ", peek() -> " + undo.peek());
// Recommended replacement
Deque<String> redo = new ArrayDeque<>();
redo.push("type A");
redo.push("type B");
redo.push("delete");
System.out.println("ArrayDeque: " + redo + ", pop() -> " + redo.pop() + ", peek() -> " + redo.peek());
}
}
Stack: [type A, type B, delete], pop() -> delete, peek() -> type B ArrayDeque: [delete, type B, type A], pop() -> delete, peek() -> type B
Notice the different printing order: Stack prints from bottom to top, while ArrayDeque prints from top to bottom. pop() and peek() give the same results.
10. Common Vector Methods
| Method | Description |
|---|---|
add(e), add(i, e) | Add at the end or at a position. |
get(i), set(i, e) | Read or replace by index. |
remove(i), remove(o) | Remove by index or by value. |
size(), isEmpty(), clear() | Count, check and empty the Vector. |
capacity() | Current length of the internal array. |
ensureCapacity(n), trimToSize() | Grow in advance, or shrink to the current size. |
setSize(n) | Cuts the Vector to n elements, or pads it with null. |
contains(o), indexOf(o), lastIndexOf(o) | Search for a value. |
indexOf(o, from) | Search starting at a given index. |
elements() | Returns an Enumeration. |
copyInto(Object[] arr) | Copies the elements into an existing array. |
11. Vector vs ArrayList
| Feature | Vector | ArrayList |
|---|---|---|
| Introduced in | JDK 1.0 (legacy) | JDK 1.2 |
| Synchronized | Yes, every method | No |
| Speed (single thread) | Slower, because of locking | Faster |
| Growth when full | Doubles, or a fixed increment | About 50% |
| Read capacity | capacity() | Not available |
| Traversal | Iterator, ListIterator and Enumeration | Iterator and ListIterator |
| Used in new code | Rarely | Yes, the default list |
12. What to Use Instead of Vector
| Your situation | Use |
|---|---|
| Only one thread uses the list | ArrayList |
| Several threads, mixed reads and writes | Collections.synchronizedList(new ArrayList<>()) |
| Several threads, mostly reads | CopyOnWriteArrayList |
| A stack | ArrayDeque |
| A producer–consumer queue | ArrayBlockingQueue or LinkedBlockingQueue |
Keep Vector only when an older API requires it, for example some Swing models.
13. Summary
- Vector is a legacy, synchronized, resizable array that implements
List. - It has a default capacity of 10 and doubles when full, unless you give a capacity increment.
- Single method calls are thread-safe, but compound actions and iteration still need a manual lock.
- It supports the old
Enumerationinterface and legacy method names. Stackextends Vector; useArrayDequefor stacks today.- In new code, use ArrayList or a concurrent collection instead.
Related Tutorials
- ArrayList in Java
- LinkedList in Java
- Difference between ArrayList and Vector
- Synchronization in Java
Reference: Java SE 21 API: java.util.Vector
Frequently Asked Questions (FAQ)
Q1. What is a Vector in Java?
Vector is a legacy class in java.util that stores elements in a resizable array, like ArrayList, but with every public method synchronized. It implements List, keeps insertion order, and allows duplicates and null.
Q2. Why is Vector called a legacy class?
It was part of JDK 1.0, before the Collections Framework arrived in JDK 1.2. It was later retrofitted to implement List, but it still carries its original method names and the Enumeration interface. Other legacy classes are Hashtable, Stack, Properties and Dictionary.
Q3. What is the default capacity of a Vector, and how does it grow?
The default capacity is 10. When it is full, the capacity doubles (10, 20, 40, 80…). If you create it with new Vector<>(initialCapacity, capacityIncrement) and a positive increment, it grows by that fixed amount instead.
Q4. Is Vector thread-safe?
Each individual method call is thread-safe because it is synchronized. Combinations of calls are not: checking isEmpty() and then calling remove() can still fail if another thread acts in between. Iteration also needs an explicit synchronized (vector) block.
Q5. Why is Vector slower than ArrayList?
Every method acquires and releases a lock, even when only one thread uses the Vector. Modern JVMs make uncontended locks cheap, but the overhead is still there, and under real contention threads have to wait for each other.
Q6. Should I use Vector in new code?
Usually not. Use ArrayList for single-threaded code, Collections.synchronizedList() or CopyOnWriteArrayList for shared lists, and ArrayDeque for stacks. Use Vector only when an existing API requires it.
Q7. What is the difference between Vector and ArrayList?
Vector is synchronized, older (JDK 1.0), doubles its capacity, supports Enumeration and has a capacity() method. ArrayList is not synchronized, faster, grows by about 50%, and is the standard list for new code. Both are backed by an array and give O(1) access by index.
Q8. What is the difference between Enumeration and Iterator?
Enumeration (JDK 1.0) only reads elements with hasMoreElements() and nextElement(), and it is not fail-fast. Iterator (JDK 1.2) uses hasNext() and next(), can remove elements, is fail-fast, and works with every collection.
Q9. Is Vector's iterator fail-fast?
Yes. The Iterator and ListIterator returned by Vector throw ConcurrentModificationException if the Vector is changed structurally other than through the iterator. The Enumeration from elements() is not fail-fast.
Q10. What does capacityIncrement mean?
It is the amount by which a Vector grows when it is full. With new Vector<>(4, 3) the capacity goes 4, 7, 10, 13… If the increment is 0 or negative (the default), the capacity doubles instead.
Q11. How is capacity() different from size()?
size() is the number of elements stored. capacity() is the length of the internal array, the number of elements the Vector can hold before it must grow. Capacity is always at least as large as size.
Q12. What does setSize() do?
setSize(n) changes the number of elements. If n is smaller than the current size, the extra elements are removed. If it is larger, the Vector is padded with null values.
Q13. Can a Vector store null and duplicate values?
Yes. A Vector accepts any number of null elements and duplicates, and it keeps elements in insertion order.
Q14. Why should I avoid the Stack class?
Stack extends Vector, so it is synchronized (slower) and exposes list methods such as add(index, e) and get(index) that let code break the last-in, first-out rule. The JDK documentation recommends Deque<E> stack = new ArrayDeque<>(); instead.
Q15. How do I iterate over a Vector safely when other threads modify it?
Hold the Vector's lock for the whole loop, or copy it first and iterate over the copy:
synchronized (vector) {
for (String s : vector) {
System.out.println(s);
}
}
// or
List<String> snapshot = new ArrayList<>(vector);
Q16. How do I convert a Vector to an ArrayList?
Pass it to the ArrayList constructor, because both are collections:
List<String> list = new ArrayList<>(vector);
Q17. Does Vector implement RandomAccess?
Yes. Like ArrayList, it is backed by an array, so get(index) runs in constant time.
Q18. Is Collections.synchronizedList() better than Vector?
They give the same level of safety: each method is synchronized, and you still lock manually for iteration and compound actions. synchronizedList() is more flexible because it can wrap any list, and it keeps your code on the modern collection API.
Q19. What are the legacy methods of Vector?
Methods from JDK 1.0 such as addElement(), insertElementAt(), elementAt(), setElementAt(), removeElement(), removeElementAt(), removeAllElements(), firstElement(), lastElement() and elements(). Each one has a standard List equivalent.
Q20. Which classes extend Vector?
In the JDK, java.util.Stack extends Vector. Some older libraries also extend it, but modern code prefers composition over extending collection classes.