1910 字
约 6 分钟
10
Java Vector和Stack
2026-09-19
无标签
第52章 Java Vector和Stack
面包屑导航 章节标题 学习目标
学习目标
- 理解Vector和Stack的基本概念和特性
- 掌握Vector和Stack的常用方法和操作
- 了解Vector与ArrayList的区别和选择
- 理解Stack与Deque的对比和使用场景
- 掌握线程安全集合的使用原则
- 学习传统集合类的最佳实践
Vector详解
Vector详解
什么是Vector?Vector是Java早期提供的动态数组实现,类似于ArrayList,但具有线程安全特性。Vector中的所有方法都是同步的,这使得它在多线程环境中是安全的,但也带来了性能开销。
Vector基本使用
import java.util.Vector;
import java.util.Enumeration;
public class VectorExample {
public static void main(String[] args) {
// 创建Vector
Vector<String> vector = new Vector<>();
// 添加元素
vector.add("Apple");
vector.add("Banana");
vector.add("Orange");
vector.addElement("Grape"); // Vector特有方法
System.out.println("Vector内容: " + vector);
System.out.println("大小: " + vector.size());
System.out.println("容量: " + vector.capacity());
// 访问元素
System.out.println("第一个元素: " + vector.firstElement());
System.out.println("最后一个元素: " + vector.lastElement());
System.out.println("索引1的元素: " + vector.elementAt(1));
// 使用Enumeration遍历(传统方式)
System.out.println("\n使用Enumeration遍历:");
Enumeration<String> enumeration = vector.elements();
while (enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
// 使用增强for循环遍历
System.out.println("\n使用增强for循环遍历:");
for (String fruit : vector) {
System.out.println(fruit);
}
// 删除元素
vector.removeElement("Banana");
vector.removeElementAt(0);
System.out.println("\n删除后: " + vector);
}
}
Stack详解
Stack详解
什么是Stack?Stack是Java提供的栈数据结构实现,继承自Vector类。它遵循LIFO(后进先出)原则,提供了push、pop、peek等栈操作方法。虽然功能完整,但现在推荐使用Deque接口的实现类。
Stack基本使用
import java.util.Stack;
import java.util.EmptyStackException;
public class StackExample {
public static void main(String[] args) {
// 创建Stack
Stack<Integer> stack = new Stack<>();
// 压入元素(push)
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
System.out.println("Stack内容: " + stack);
System.out.println("栈顶元素: " + stack.peek());
// 弹出元素(pop)
System.out.println("\n弹出操作:");
while (!stack.isEmpty()) {
System.out.println("弹出: " + stack.pop());
if (!stack.isEmpty()) {
System.out.println("当前栈顶: " + stack.peek());
}
}
// 演示空栈异常
try {
stack.pop(); // 空栈弹出会抛出异常
} catch (EmptyStackException e) {
System.out.println("\n空栈异常: " + e.getMessage());
}
// 栈的实际应用:括号匹配
System.out.println("\n括号匹配测试:");
System.out.println("\"()\" 匹配: " + isValidParentheses("()"));
System.out.println("\"()[]{}\" 匹配: " + isValidParentheses("()[]{}"));
System.out.println("\"([)]\" 匹配: " + isValidParentheses("([)]"));
}
// 使用栈检查括号匹配
public static boolean isValidParentheses(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else if (c == ')' || c == ']' || c == '}') {
if (stack.isEmpty()) return false;
char top = stack.pop();
if ((c == ')' && top != '(') ||
(c == ']' && top != '[') ||
(c == '}' && top != '{')) {
return false;
}
}
}
return stack.isEmpty();
}
}
Vector vs ArrayList对比
Vector vs ArrayList对比
| 特性 | Vector | ArrayList |
|---|---|---|
| 线程安全 | ✅ 同步,线程安全 | ❌ 非同步,线程不安全 |
| 性能 | 较慢(同步开销) | 较快 |
| 扩容机制 | 默认扩容100%(翻倍) | 扩容50% |
| 引入版本 | JDK 1.0 | JDK 1.2 |
| 遍历方式 | Iterator, Enumeration, for-each | Iterator, for-each |
| 推荐使用 | 不推荐(遗留类) | 推荐 |
使用建议在现代Java开发中,通常不推荐使用Vector。如果需要线程安全的List,建议使用:Collections.synchronizedList(new ArrayList<>())CopyOnWriteArrayList(读多写少场景)使用并发控制机制保护ArrayList
Stack vs Deque对比
Stack vs Deque对比
传统Stack
- 继承自Vector,线程安全
- 提供push、pop、peek方法
- 性能较差(同步开销)
- 功能单一,只能栈操作
- 不推荐在新项目中使用
现代Deque
- 接口设计,多种实现
- 支持双端操作
- 性能更好
- 功能更丰富
- 推荐使用ArrayDeque或LinkedList
Deque替代Stack示例
import java.util.Deque;
import java.util.ArrayDeque;
public class DequeAsStack {
public static void main(String[] args) {
// 使用Deque作为栈
Deque<String> stack = new ArrayDeque<>();
// 栈操作
stack.push("First"); // 等同于addFirst
stack.push("Second");
stack.push("Third");
System.out.println("栈内容: " + stack);
System.out.println("栈顶元素: " + stack.peek()); // 等同于peekFirst
// 弹出所有元素
while (!stack.isEmpty()) {
System.out.println("弹出: " + stack.pop()); // 等同于removeFirst
}
// Deque的额外功能:双端操作
Deque<Integer> deque = new ArrayDeque<>();
// 从两端添加
deque.addFirst(1);
deque.addLast(2);
deque.addFirst(0);
deque.addLast(3);
System.out.println("\nDeque内容: " + deque);
// 从两端移除
System.out.println("从前端移除: " + deque.removeFirst());
System.out.println("从后端移除: " + deque.removeLast());
System.out.println("剩余内容: " + deque);
}
}
完整代码示例
完整代码示例
import java.util.*;
/**
* Vector和Stack综合示例
* 演示传统集合类的使用和现代替代方案
*/
public class VectorStackDemo {
public static void main(String[] args) {
System.out.println("=== Vector示例 ===");
vectorExample();
System.out.println("\n=== Stack示例 ===");
stackExample();
System.out.println("\n=== 现代替代方案 ===");
modernAlternatives();
}
/**
* Vector使用示例
*/
public static void vectorExample() {
Vector<String> vector = new Vector<>();
// 添加元素
vector.add("Java");
vector.add("Python");
vector.add("JavaScript");
// Vector特有方法
System.out.println("容量: " + vector.capacity());
System.out.println("大小: " + vector.size());
// 线程安全测试(简单演示)
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
vector.add("Thread1-" + i);
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
vector.add("Thread2-" + i);
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终Vector大小: " + vector.size());
}
/**
* Stack使用示例:表达式求值
*/
public static void stackExample() {
String expression = "3 + 4 * 2";
System.out.println("表达式: " + expression);
System.out.println("结果: " + evaluateExpression(expression));
}
/**
* 简单的表达式求值(仅支持+和*)
*/
public static int evaluateExpression(String expression) {
Stack<Integer> numbers = new Stack<>();
Stack<Character> operators = new Stack<>();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == ' ') continue;
if (Character.isDigit(c)) {
numbers.push(c - '0');
} else if (c == '+' || c == '*') {
while (!operators.isEmpty() &&
precedence(operators.peek()) >= precedence(c)) {
int b = numbers.pop();
int a = numbers.pop();
char op = operators.pop();
numbers.push(calculate(a, b, op));
}
operators.push(c);
}
}
while (!operators.isEmpty()) {
int b = numbers.pop();
int a = numbers.pop();
char op = operators.pop();
numbers.push(calculate(a, b, op));
}
return numbers.pop();
}
private static int precedence(char op) {
return op == '*' ? 2 : 1;
}
private static int calculate(int a, int b, char op) {
return op == '+' ? a + b : a * b;
}
/**
* 现代替代方案示例
*/
public static void modernAlternatives() {
// 使用ArrayList + 同步包装器替代Vector
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add("Modern");
syncList.add("Approach");
System.out.println("同步List: " + syncList);
// 使用ArrayDeque替代Stack
Deque<Integer> modernStack = new ArrayDeque<>();
modernStack.push(1);
modernStack.push(2);
modernStack.push(3);
System.out.println("现代栈: " + modernStack);
System.out.println("弹出: " + modernStack.pop());
// CopyOnWriteArrayList用于读多写少场景
List<String> cowList = new CopyOnWriteArrayList<>();
cowList.add("Thread-Safe");
cowList.add("Read-Optimized");
System.out.println("CopyOnWrite List: " + cowList);
}
}
💻 查看完整代码 - 在线IDE体验 最佳实践
最佳实践
Vector和Stack使用建议
推荐做法
- 新项目中使用ArrayList + 同步机制
- 使用ArrayDeque替代Stack
- 读多写少场景考虑CopyOnWriteArrayList
- 明确线程安全需求再选择集合
- 性能敏感场景避免不必要的同步
避免做法
- 在新项目中直接使用Vector
- 不考虑性能就使用同步集合
- 混用传统和现代集合API
- 忽略集合的扩容机制影响
- 在单线程环境使用同步集合
本章小结
本章小结
- Vector是线程安全的动态数组,但性能较ArrayList差,现在不推荐使用
- Stack继承自Vector,提供LIFO栈操作,但推荐使用Deque接口的实现
- Vector的扩容机制是翻倍增长,而ArrayList是50%增长
- 现代Java开发中,推荐使用ArrayList + 同步机制替代Vector
- ArrayDeque是Stack的现代替代方案,性能更好且功能更丰富
- 选择集合类时要考虑线程安全需求、性能要求和功能特性
- 理解传统集合类有助于维护遗留代码和技术面试
导航链接 上一章:LinkedList 章节测试 下一章:Set接口 JavaScript
评论
0 条
还没有评论,先写一条吧。