BhauAutomation

Java Vector & Stack

Java Vector and Java Stack are legacy collection classes in Java that provide dynamic array functionality and LIFO data structure operations. Learn how they work, their differences, and practical usage in Java programming.

📘 Topic: Java Collections / Data Structures
Read time: 7 min
📊 Level: Intermediate
📚 Focus: Legacy Collections
📖 Overview

📦 Java Vector

Java Vector is a dynamic array that can grow or shrink in size. It is part of the Java Collection Framework and is synchronized, making it thread-safe. Vector is a legacy class (since Java 1.0) but was retrofitted to implement the List interface. It maintains insertion order and allows duplicate elements.

🥞 Java Stack

Java Stack is a collection class representing a last-in-first-out (LIFO) stack of objects. It extends the Vector class and provides specialized operations like push, pop, and peek. Stack was also part of the original Java release and is synchronized (inherits thread-safety from Vector).

📦 Vector

Java Vector

🎯 Objectives of Java Vector

Java Vector allows dynamic storage of elements that can grow or shrink automatically. It provides thread-safe operations for multi-threaded environments and offers standard methods for adding, removing, and accessing elements by index.

✅ Advantages

Vector resizes dynamically (increments capacity by 100% when full), is synchronized for thread safety (except when iterating), implements all List interface methods, and maintains insertion order. It also provides Enumeration for backward compatibility.

⚠️ Limitations

Vector is slower than ArrayList due to synchronization overhead (even when not required). Considered a legacy class, it's generally recommended to use ArrayList for non-threaded applications and Collections.synchronizedList() for thread-safety with better performance.

🔧 Common Vector Methods

add(E e) addElement(E e) remove(int index) removeElement(Object o) get(int index) elementAt(int index) size() capacity() setSize(int newSize) clear() contains(Object o) indexOf(Object o)

💻 Example

import java.util.Vector; import java.util.Enumeration; public class VectorExample { public static void main(String[] args) { // Create a Vector Vector<String> vec = new Vector<>(); // Adding elements vec.add("Apple"); vec.add("Banana"); vec.addElement("Orange"); vec.add(1, "Mango"); // Insert at index 1 System.out.println("Vector: " + vec); System.out.println("Size: " + vec.size()); System.out.println("Capacity: " + vec.capacity()); System.out.println("Element at index 2: " + vec.get(2)); // Removing elements vec.remove("Banana"); vec.removeElementAt(0); System.out.println("After removal: " + vec); // Using Enumeration (legacy) Enumeration<String> en = vec.elements(); System.out.print("Enumeration: "); while (en.hasMoreElements()) { System.out.print(en.nextElement() + " "); } // Iterating with for-each System.out.print("\nFor-each: "); for (String fruit : vec) { System.out.print(fruit + " "); } } }
🥞 Stack

Java Stack

🎯 Objectives of Java Stack

Java Stack allows elements to be stored in LIFO (Last-In-First-Out) order, supports push/pop/peek operations, provides easy access to the top element, and is useful for parsing expressions, undo/redo operations, and backtracking algorithms.

✅ Advantages

Stack provides LIFO behavior suitable for function call management, expression evaluation (postfix/infix), undo mechanisms, and backtracking algorithms. It is thread-safe because it inherits synchronization from Vector and provides O(1) push/pop operations.

⚠️ Limitations

Stack is slower than non-synchronized collections (Deque implementations like ArrayDeque are preferred for single-threaded applications). It is limited to LIFO operations only and extends Vector, which adds unnecessary functionality for a pure Stack implementation.

🔧 Stack Methods

push(E item) pop() peek() empty() search(Object o)

💻 Example

import java.util.Stack; public class StackExample { public static void main(String[] args) { // Create a Stack Stack<Integer> stack = new Stack<>(); // Push elements (add to top) stack.push(10); stack.push(20); stack.push(30); stack.push(40); System.out.println("Stack: " + stack); System.out.println("Top element (peek): " + stack.peek()); System.out.println("Is empty? " + stack.empty()); // Pop elements (remove from top) System.out.println("Popped: " + stack.pop()); System.out.println("After pop: " + stack); // Search for element (returns 1-based position from top) System.out.println("Position of 20: " + stack.search(20)); // Complete stack usage example - Browser Back Button Stack<String> browserHistory = new Stack<>(); browserHistory.push("Homepage"); browserHistory.push("Products"); browserHistory.push("Product Details"); System.out.println("\nBrowser History: " + browserHistory); System.out.println("Back to: " + browserHistory.pop()); System.out.println("Current page: " + browserHistory.peek()); // While stack is not empty while (!browserHistory.isEmpty()) { System.out.println("Clearing: " + browserHistory.pop()); } } }
📊 Comparison

Difference Between Java Vector & Java Stack

Aspect Java Vector Java Stack
Data Structure Dynamic Array (resizable) LIFO Stack (Last-In-First-Out)
Inheritance Extends AbstractList, implements List Extends Vector (inherits all Vector properties)
Ordering Maintains insertion order Reverse of insertion order (LIFO)
Primary Operations add(index, element), remove(index), get(index) push(), pop(), peek()
Access Style Index-based random access Top-only access (LIFO)
Thread-safety Synchronized (thread-safe) Synchronized (inherited from Vector)
Recommended Alternative ArrayList (non-synchronized) ArrayDeque (better performance)
🏆 Best Practices

Best Practices for Vector & Stack

Use ArrayList instead of Vector for single-threaded applications (better performance)

For thread-safety, consider Collections.synchronizedList(new ArrayList<>()) over Vector

Use ArrayDeque instead of Stack for modern Java applications (faster and better memory usage)

Always check if the stack is empty using isEmpty() before calling pop() or peek()

Specify initial capacity for Vector to reduce resizing overhead

Use for-each loops instead of Enumeration for iteration (cleaner and more efficient)