Vector Class
Overview
- Synchronized (thread-safe) implementation of dynamic array
- Legacy class from Java 1.0
- Implements
Listinterface - 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
Vectorclass - Synchronized (thread-safe)
- Legacy class - Consider using
Dequeinstead 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()orCopyOnWriteArrayListfor thread safety, andArrayDequefor 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.