00:00

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 null allowed.
  • 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() and elementAt(), and the Enumeration interface.
  • Fail-fast iterators: the Iterator and ListIterator throw ConcurrentModificationException if 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.

Vector class hierarchy in Java
java.util.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().

VectorQuickStart.java
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);
    }
}
Output
Vector:   [Red, Blue, Green]
get(0):   Red
size:     3
capacity: 10
After remove: [Red, Blue]

4. Constructors

ConstructorWhat 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.

VectorCapacity.java
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());
    }
}
Output
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.

VectorLegacyMethods.java
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);
    }
}
Output
Vector:          [Mon, Tue, Wed]
firstElement():  Mon
lastElement():   Wed
elementAt(1):    Tue
After changes:   [Tue, Wednesday]
After setSize(4): [Tue, Wednesday, null, null]
Legacy methodModern 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.

VectorEnumeration.java
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);
    }
}
Output
Agra Bhopal Chennai 
After Iterator.remove(): [Agra, Chennai]
FeatureEnumerationIterator
Introduced inJDK 1.0JDK 1.2
MethodshasMoreElements(), nextElement()hasNext(), next(), remove()
Can remove elementsNoYes
Fail-fastNoYes
Works withLegacy 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.

VectorThreads.java
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());
    }
}
Output
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.

StackExample.java
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());
    }
}
Output
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

MethodDescription
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

FeatureVectorArrayList
Introduced inJDK 1.0 (legacy)JDK 1.2
SynchronizedYes, every methodNo
Speed (single thread)Slower, because of lockingFaster
Growth when fullDoubles, or a fixed incrementAbout 50%
Read capacitycapacity()Not available
TraversalIterator, ListIterator and EnumerationIterator and ListIterator
Used in new codeRarelyYes, the default list

12. What to Use Instead of Vector

Your situationUse
Only one thread uses the listArrayList
Several threads, mixed reads and writesCollections.synchronizedList(new ArrayList<>())
Several threads, mostly readsCopyOnWriteArrayList
A stackArrayDeque
A producer–consumer queueArrayBlockingQueue 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 Enumeration interface and legacy method names.
  • Stack extends Vector; use ArrayDeque for stacks today.
  • In new code, use ArrayList or a concurrent collection instead.

Related Tutorials

Reference: Java SE 21 API: java.util.Vector