📦 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).
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
💻 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 + " ");
}
}
}
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
💻 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());
}
}
}
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 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)