DevNotes
Support
Collection Framework · Chapter 06

Vector & Stack

The legacy synchronized list and LIFO stack — capacity increment, Enumeration, and why ArrayDeque replaced Stack.

◷ 6 min read§ 20 sections? 9 interview questions{ } 15 code examples

#Introduction

Vector and Stack are considered legacy collection classes, but they are still frequently asked in interviews because they help interviewers evaluate your understanding of the evolution of the Java Collections Framework, thread safety, and legacy vs modern APIs.

Although you may rarely use them in new applications, you must know how they work and why modern alternatives are preferred.

#History of Vector

Before the Java Collections Framework (JDK 1.2), Java provided a few collection-like classes. One of them was Vector.

After JDK 1.2, Vector was modified to implement the List interface. That means today it behaves like a normal List while retaining its original synchronized behaviour.

#What is Vector?

Vector is a synchronized, resizable array implementation of the List interface.

Package:

Java
java.util.Vector

Declaration:

Java
public class Vector<E>
        extends AbstractList<E>
        implements List<E>,
                   RandomAccess,
                   Cloneable,
                   Serializable

Like ArrayList, Vector implements RandomAccess because internally it also uses an array.

Iterable
Collection
List
Vector
Stack
Position in hierarchy

#Characteristics of Vector

  • Maintains insertion order
  • Allows duplicates
  • Allows null values
  • Dynamic resizing
  • Thread-safe
  • Slower than ArrayList
  • Legacy class

#Internal Structure

Exactly like ArrayList, Vector stores elements inside:

Java
Object[] elementData;
[0]
A
[1]
B
[2]
C
[3]
D
[4]
E
Internally it is still an array

#Why is Vector Thread-Safe?

Interview favourite. Every public method is synchronized:

Java
public synchronized boolean add(E e)

Meaning: only one thread can modify the Vector at a time.

Thread Alock Vector
Insert
Unlock
Thread Bcan now enter
This prevents concurrent modification issues

#Synchronization Cost

Java
vector.add("Java");
Acquire Lock
Insert
Release Lock
This additional locking introduces overhead

#Creating a Vector

Default Constructor

Java
Vector<Integer> vector = new Vector<>();

Default capacity: 10.

Initial Capacity

Java
Vector<Integer> vector = new Vector<>(100);

Capacity: 100.

Capacity Increment

A unique feature of Vector.

Java
Vector<Integer> vector = new Vector<>(10, 5);

Initial capacity 10, capacity increment 5.

10
15
20
25
Growth with capacityIncrement = 5

#Growth Algorithm

Interview favourite. If no capacity increment is specified, Vector doubles its capacity.

Vector (doubles)
10
20
40
80
ArrayList (~1.5×)
10
15
22
33

#Size vs Capacity

Java
Vector<Integer> vector = new Vector<>();

After adding 5 elements: Size = 5, Capacity = 10 — exactly like ArrayList.

#Important Methods

MethodDescription
vector.add("Java")Adds at end
vector.addElement("Java")Legacy method — same purpose
vector.remove(2)Removes element
removeElement()Legacy version of remove
vector.elementAt(2)Legacy API instead of vector.get(2)
vector.firstElement()Returns first element
vector.lastElement()Returns last element
vector.capacity()Returns current capacity

Vector Example

Java
Vector<String> vector = new Vector<>();
vector.add("Java");
vector.add("Spring");
vector.add("Docker");
System.out.println(vector);
Output
[Java, Spring, Docker]

#Enumeration

Before Iterator, Java used Enumeration.

Java
Enumeration<String> e = vector.elements();

while (e.hasMoreElements()) {
    System.out.println(e.nextElement());
}

Enumeration is still supported for backward compatibility.

Enumeration vs Iterator

FeatureEnumerationIterator
LegacyYesNo
Remove ElementsNoYes
Forward TraversalYesYes
Fail-FastNoYes

#Stack

What is Stack?

Stack extends Vector.

Java
public class Stack<E> extends Vector<E>

Meaning: every Vector method is available inside Stack.

LIFO Principle

Stack follows LIFO — Last In, First Out.

30top
20
10
Push 10, 20, 30 — pop() returns 30 first

#Stack Operations

OperationCodeDescription
push()stack.push(10);Adds to top
pop()stack.pop();Removes top element
peek()stack.peek();Returns top element without removing it
empty()stack.empty();Checks whether the stack is empty
search()stack.search(20);Returns distance from top (1-based)

search() Example

Java
Stack<Integer> stack = new Stack<>();
stack.push(10);
stack.push(20);
stack.push(30);
System.out.println(stack.search(20));
Output
2

Stack Example

Java
Stack<String> stack = new Stack<>();
stack.push("Java");
stack.push("Spring");
stack.push("AWS");
System.out.println(stack.pop());
System.out.println(stack.peek());
Output
AWS
Spring

#Why is Stack Legacy?

Interview favourite. Because it extends Vector, every operation is synchronized — extra overhead. Modern Java recommends ArrayDeque instead.

ArrayDeque vs Stack

FeatureStackArrayDeque
Thread-SafeYes (via Vector synchronization)No
LegacyYesNo
PerformanceSlowerFaster
RecommendedNoYes

Why is ArrayDeque Preferred?

  • Faster
  • No synchronization overhead
  • Better memory usage
  • Designed specifically for Queue and Stack operations
Java
Deque<Integer> stack = new ArrayDeque<>();

stack.push(10);
stack.push(20);

System.out.println(stack.pop());
Output
20

#Vector vs ArrayList

FeatureVectorArrayList
Thread-SafeYesNo
Internal StructureDynamic ArrayDynamic Array
SynchronizationYesNo
PerformanceSlowerFaster
Growth2× (default)~1.5×
LegacyYesNo
Capacity APIYesNo

#Time Complexity

OperationComplexity
get()O(1)
set()O(1)
add()O(1) amortized
remove(index)O(n)
contains()O(n)
iterationO(n)
push()O(1)
pop()O(1)
peek()O(1)

#Common Mistakes

  • Using Stack in new projects. Better: Deque<Integer> stack = new ArrayDeque<>();
  • Using Vector assuming it is always the correct thread-safe list. Modern alternatives include Collections.synchronizedList() and CopyOnWriteArrayList, depending on the use case.
  • Thinking synchronization means "better". Synchronization improves thread safety but also adds performance overhead.

#Frequently Asked Interview Questions

Q1Difference between Vector and ArrayList?
  • Vector is synchronized; ArrayList is not.
  • Vector is slower because of locking.
  • Vector doubles capacity by default; ArrayList grows by approximately 1.5×.
Q2Why is Vector slower?

Because every public method is synchronized, requiring lock acquisition and release.

Q3What is the default capacity of Vector?

10.

Q4What is Capacity Increment?

A Vector-specific feature that allows you to specify how much the internal array should grow when it becomes full.

Q5What is Enumeration?

A legacy traversal interface introduced before Iterator. It supports forward traversal but cannot remove elements.

Q6Why is Stack considered legacy?

Because it extends Vector, inherits synchronization overhead, and has been superseded by Deque implementations such as ArrayDeque.

Q7Which should be used instead of Stack?

ArrayDeque.

Q8Is Vector always the best choice for multi-threaded applications?

No. Modern concurrent collections such as CopyOnWriteArrayList or properly synchronized wrappers are often better choices, depending on the workload.

#Chapter Summary

  • Vector is a synchronized, resizable array implementation of List.
  • It uses an internal Object[] just like ArrayList.
  • Every public method is synchronized, making it thread-safe but slower.
  • Vector supports a unique capacityIncrement feature.
  • Stack extends Vector and follows the LIFO principle.
  • Modern Java recommends ArrayDeque instead of Stack.
  • Enumeration is a legacy traversal mechanism; Iterator is the modern replacement.