Vector and Stack in Java – Complete Guide

Vector Class

Overview

  • Synchronized (thread-safe) implementation of dynamic array
  • Legacy class from Java 1.0
  • Implements List interface
  • Grows automatically as needed

Basic Vector Operations

import java.util.*;
public class VectorBasicExample {
public static void main(String[] args) {
// Creating Vector
Vector<String> vector = new Vector<>();
// Adding elements
vector.add("Apple");
vector.add("Banana");
vector.addElement("Orange"); // Legacy method
vector.add(1, "Mango"); // Insert at specific position
System.out.println("Vector: " + vector);
// Accessing elements
System.out.println("Element at index 0: " + vector.get(0));
System.out.println("First element: " + vector.firstElement());
System.out.println("Last element: " + vector.lastElement());
// Size and capacity
System.out.println("Size: " + vector.size());
System.out.println("Capacity: " + vector.capacity());
// Checking existence
System.out.println("Contains 'Apple': " + vector.contains("Apple"));
System.out.println("Index of 'Banana': " + vector.indexOf("Banana"));
}
}

Vector Constructors

import java.util.*;
public class VectorConstructors {
public static void main(String[] args) {
// 1. Default constructor (capacity: 10)
Vector<Integer> v1 = new Vector<>();
System.out.println("Default capacity: " + v1.capacity());
// 2. With initial capacity
Vector<Integer> v2 = new Vector<>(20);
System.out.println("Capacity 20: " + v2.capacity());
// 3. With initial capacity and capacity increment
Vector<Integer> v3 = new Vector<>(10, 5);
System.out.println("Initial capacity: " + v3.capacity());
// Add elements to see capacity growth
for (int i = 0; i < 15; i++) {
v3.add(i);
}
System.out.println("After adding 15 elements, capacity: " + v3.capacity());
// 4. From existing collection
List<String> list = Arrays.asList("A", "B", "C");
Vector<String> v4 = new Vector<>(list);
System.out.println("Vector from collection: " + v4);
}
}

Vector Capacity Management

import java.util.*;
public class VectorCapacityExample {
public static void main(String[] args) {
Vector<Integer> vector = new Vector<>(5, 3); // Initial: 5, Increment: 3
System.out.println("Initial capacity: " + vector.capacity());
System.out.println("Size: " + vector.size());
// Add elements to trigger capacity increase
for (int i = 1; i <= 10; i++) {
vector.add(i);
System.out.println("Added " + i + " - Size: " + vector.size() + 
", Capacity: " + vector.capacity());
}
// Capacity management methods
vector.ensureCapacity(20); // Ensure minimum capacity
System.out.println("After ensureCapacity(20): " + vector.capacity());
vector.trimToSize(); // Trim to current size
System.out.println("After trimToSize(): " + vector.capacity());
}
}

Vector Enumeration (Legacy)

import java.util.*;
public class VectorEnumerationExample {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Java");
vector.add("Python");
vector.add("C++");
vector.add("JavaScript");
// Using Enumeration (legacy)
System.out.println("Using Enumeration:");
Enumeration<String> enumeration = vector.elements();
while (enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
// Using Iterator (modern)
System.out.println("\nUsing Iterator:");
Iterator<String> iterator = vector.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// Using for-each loop
System.out.println("\nUsing for-each:");
for (String language : vector) {
System.out.println(language);
}
// Using forEach with lambda (Java 8+)
System.out.println("\nUsing forEach with lambda:");
vector.forEach(lang -> System.out.println(lang));
}
}

Vector vs ArrayList

import java.util.*;
public class VectorVsArrayList {
public static void main(String[] args) {
// Vector is synchronized
Vector<String> vector = new Vector<>();
vector.add("A");
vector.add("B");
// ArrayList is not synchronized
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
// Making ArrayList synchronized
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// Performance comparison
int size = 100000;
// Vector performance
long startTime = System.currentTimeMillis();
Vector<Integer> v = new Vector<>();
for (int i = 0; i < size; i++) {
v.add(i);
}
long vectorTime = System.currentTimeMillis() - startTime;
// ArrayList performance
startTime = System.currentTimeMillis();
ArrayList<Integer> al = new ArrayList<>();
for (int i = 0; i < size; i++) {
al.add(i);
}
long arrayListTime = System.currentTimeMillis() - startTime;
System.out.println("Vector time: " + vectorTime + "ms");
System.out.println("ArrayList time: " + arrayListTime + "ms");
}
}

Thread-Safe Vector Operations

import java.util.*;
public class VectorThreadSafety {
public static void main(String[] args) throws InterruptedException {
Vector<Integer> sharedVector = new Vector<>();
// Create multiple threads that modify the vector
Thread writer1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
sharedVector.add(i);
}
});
Thread writer2 = new Thread(() -> {
for (int i = 1000; i < 2000; i++) {
sharedVector.add(i);
}
});
Thread reader = new Thread(() -> {
// Safe to iterate even while other threads modify
synchronized (sharedVector) {
Iterator<Integer> it = sharedVector.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
});
writer1.start();
writer2.start();
Thread.sleep(100); // Let writers add some elements
reader.start();
writer1.join();
writer2.join();
reader.join();
System.out.println("\nFinal size: " + sharedVector.size());
}
}

Stack Class

Overview

  • LIFO (Last-In-First-Out) data structure
  • Extends Vector class
  • Synchronized (thread-safe)
  • Legacy class - Consider using Deque instead for new code

Basic Stack Operations

import java.util.*;
public class StackBasicExample {
public static void main(String[] args) {
// Creating Stack
Stack<String> stack = new Stack<>();
// Pushing elements (adding to top)
stack.push("First");
stack.push("Second");
stack.push("Third");
stack.push("Fourth");
System.out.println("Stack: " + stack);
// Peeking (view top element without removal)
System.out.println("Top element: " + stack.peek());
// Popping elements (removing from top)
System.out.println("Popped: " + stack.pop());
System.out.println("Popped: " + stack.pop());
System.out.println("Stack after pops: " + stack);
// Searching (returns 1-based position from top)
System.out.println("Position of 'First': " + stack.search("First"));
System.out.println("Position of 'Second': " + stack.search("Second")); // -1, not found
// Checking if empty
System.out.println("Is stack empty? " + stack.isEmpty());
// Emptying the stack
while (!stack.isEmpty()) {
System.out.println("Popping: " + stack.pop());
}
System.out.println("Stack empty? " + stack.isEmpty());
}
}

Stack Use Cases

1. Expression Evaluation

import java.util.*;
public class ExpressionEvaluation {
public static boolean isBalanced(String expression) {
Stack<Character> stack = new Stack<>();
for (char ch : expression.toCharArray()) {
if (ch == '(' || ch == '[' || ch == '{') {
stack.push(ch);
} else if (ch == ')' || ch == ']' || ch == '}') {
if (stack.isEmpty()) return false;
char top = stack.pop();
if ((ch == ')' && top != '(') ||
(ch == ']' && top != '[') ||
(ch == '}' && top != '{')) {
return false;
}
}
}
return stack.isEmpty();
}
public static void main(String[] args) {
String[] expressions = {
"((2+3)*5)",
"{[()]}",
"((2+3)*5",
"[(])"
};
for (String expr : expressions) {
System.out.println(expr + " is balanced: " + isBalanced(expr));
}
}
}

2. Undo/Redo Functionality

import java.util.*;
class TextEditor {
private Stack<String> undoStack = new Stack<>();
private Stack<String> redoStack = new Stack<>();
private String currentText = "";
public void write(String text) {
undoStack.push(currentText);
currentText += text;
redoStack.clear(); // Clear redo stack on new write
System.out.println("Text: " + currentText);
}
public void undo() {
if (!undoStack.isEmpty()) {
redoStack.push(currentText);
currentText = undoStack.pop();
System.out.println("Undo - Text: " + currentText);
} else {
System.out.println("Nothing to undo");
}
}
public void redo() {
if (!redoStack.isEmpty()) {
undoStack.push(currentText);
currentText = redoStack.pop();
System.out.println("Redo - Text: " + currentText);
} else {
System.out.println("Nothing to redo");
}
}
}
public class UndoRedoExample {
public static void main(String[] args) {
TextEditor editor = new TextEditor();
editor.write("Hello");
editor.write(" World");
editor.write("!");
editor.undo();
editor.undo();
editor.redo();
editor.redo();
}
}

3. Browser History

import java.util.*;
class Browser {
private Stack<String> backStack = new Stack<>();
private Stack<String> forwardStack = new Stack<>();
private String currentPage = "home";
public void visit(String url) {
backStack.push(currentPage);
currentPage = url;
forwardStack.clear(); // Clear forward stack on new visit
System.out.println("Visited: " + currentPage);
}
public void back() {
if (!backStack.isEmpty()) {
forwardStack.push(currentPage);
currentPage = backStack.pop();
System.out.println("Back to: " + currentPage);
} else {
System.out.println("Can't go back");
}
}
public void forward() {
if (!forwardStack.isEmpty()) {
backStack.push(currentPage);
currentPage = forwardStack.pop();
System.out.println("Forward to: " + currentPage);
} else {
System.out.println("Can't go forward");
}
}
public String getCurrentPage() {
return currentPage;
}
}
public class BrowserHistoryExample {
public static void main(String[] args) {
Browser browser = new Browser();
browser.visit("google.com");
browser.visit("github.com");
browser.visit("stackoverflow.com");
browser.back();
browser.back();
browser.forward();
browser.visit("leetcode.com");
browser.forward(); // Can't go forward after new visit
}
}

Stack with Custom Objects

import java.util.*;
class Book {
private String title;
private String author;
private int year;
public Book(String title, String author, int year) {
this.title = title;
this.author = author;
this.year = year;
}
public String getTitle() { return title; }
public String getAuthor() { return author; }
public int getYear() { return year; }
@Override
public String toString() {
return title + " by " + author + " (" + year + ")";
}
}
public class StackWithObjects {
public static void main(String[] args) {
Stack<Book> bookStack = new Stack<>();
// Push books onto stack
bookStack.push(new Book("Effective Java", "Joshua Bloch", 2018));
bookStack.push(new Book("Clean Code", "Robert Martin", 2008));
bookStack.push(new Book("Head First Java", "Kathy Sierra", 2005));
System.out.println("Books in stack (LIFO order):");
// Process books in LIFO order
while (!bookStack.isEmpty()) {
Book book = bookStack.pop();
System.out.println("Processing: " + book);
}
}
}

Modern Alternative to Stack

import java.util.*;
public class DequeAsStack {
public static void main(String[] args) {
// Using ArrayDeque as stack (recommended for new code)
Deque<String> stack = new ArrayDeque<>();
// Push operations
stack.push("First");
stack.push("Second");
stack.push("Third");
System.out.println("Stack: " + stack);
// Peek operation
System.out.println("Top element: " + stack.peek());
// Pop operations
System.out.println("Popped: " + stack.pop());
System.out.println("Popped: " + stack.pop());
System.out.println("Remaining: " + stack);
// Additional Deque operations
stack.addLast("New Last"); // Equivalent to push for stack behavior
stack.addFirst("New First");
System.out.println("After additions: " + stack);
}
}

Complete Stack Implementation Example

import java.util.*;
public class CompleteStackExample {
// Method to reverse a list using stack
public static <T> List<T> reverseList(List<T> list) {
Stack<T> stack = new Stack<>();
List<T> reversed = new ArrayList<>();
// Push all elements onto stack
for (T element : list) {
stack.push(element);
}
// Pop elements to get reversed order
while (!stack.isEmpty()) {
reversed.add(stack.pop());
}
return reversed;
}
// Method to check palindrome using stack
public static boolean isPalindrome(String str) {
Stack<Character> stack = new Stack<>();
String cleanStr = str.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
// Push first half of characters
for (int i = 0; i < cleanStr.length() / 2; i++) {
stack.push(cleanStr.charAt(i));
}
// Start from middle (adjust for odd length)
int startIndex = cleanStr.length() / 2;
if (cleanStr.length() % 2 != 0) {
startIndex++;
}
// Compare with second half
for (int i = startIndex; i < cleanStr.length(); i++) {
if (stack.pop() != cleanStr.charAt(i)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
// Test reverse list
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Diana");
System.out.println("Original: " + names);
System.out.println("Reversed: " + reverseList(names));
// Test palindrome
String[] testStrings = {"racecar", "hello", "A man a plan a canal Panama"};
for (String str : testStrings) {
System.out.println("'" + str + "' is palindrome: " + isPalindrome(str));
}
}
}

Key Points to Remember

Vector:

  • Synchronized - Thread-safe but slower than ArrayList
  • Dynamic array - Grows automatically
  • Legacy class - Use ArrayList for better performance in single-threaded environments
  • Capacity management - Can specify initial capacity and increment

Stack:

  • LIFO principle
  • Extends Vector - Inherits all Vector methods
  • Legacy class - Use Deque interface with ArrayDeque for better performance
  • Common use cases: Expression evaluation, undo/redo, backtracking

When to Use:

  • Vector: When thread safety is needed and performance is not critical
  • Stack: When LIFO behavior is required in legacy code
  • Alternatives: Use Collections.synchronizedList() or CopyOnWriteArrayList for thread safety, and ArrayDeque for stack operations

Both Vector and Stack are legacy classes and generally not recommended for new code, but they're important to understand for maintaining existing applications.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper