JDK 內建 java.util.Stack<E> 繼承自 Vector,所有方法同步化,效能較差且設計較舊。現代開發推薦使用 Deque<E>(ArrayDeque)或自行封裝。本範例展示如何用泛型 + LinkedList 實現一個乾淨、型別安全的 Stack<T>。
package cn.edu.xidian.crytoll;
import java.util.LinkedList;
public class Stack<T> {
private final LinkedList<T> container = new LinkedList<>();
/** 入棧:插入到鏈表頭部 O(1) */
public void push(T t) {
container.addFirst(t);
}
/** 出棧:移除並返回鏈表頭部 O(1) */
public T pop() {
return container.removeFirst();
}
/** 判空 */
public boolean empty() {
return container.isEmpty();
}
/** 可選:查看棧頂不移除 */
public T peek() {
return container.peekFirst();
}
/** 可選:棧大小 */
public int size() {
return container.size();
}
}
package cn.edu.xidian.crytoll;
public class StackTest {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
System.out.println("向棧中增加字符串:");
System.out.println("視頻學Java");
System.out.println("細說Java");
System.out.println("Java從入門到精通(第2版)");
stack.push("視頻學Java");
stack.push("細說Java");
stack.push("Java從入門到精通(第2版)");
System.out.println("從棧中取出字符串(LIFO):");
while (!stack.empty()) {
System.out.println(stack.pop());
}
}
}
向棧中增加字符串:
視頻學Java
細說Java
Java從入門到精通(第2版)
從棧中取出字符串(LIFO):
Java從入門到精通(第2版)
細說Java
視頻學Java
| 操作 | LinkedList 方法 | 時間複雜度 | 說明 |
|---|---|---|---|
| push | addFirst | O(1) | 頭部插入,無需位移 |
| pop | removeFirst | O(1) | 頭部移除,返回元素 |
| peek | peekFirst | O(1) | 僅檢視不移除 |
| empty | isEmpty | O(1) | 委派給鏈表 |
ArrayList.add(0, e) / remove(0) 需搬移所有元素,O(n)。LinkedList 節點操作只涉及指標調整,O(1) 穩定。addFirst/removeFirst 完美契合。Stack<String> 編譯期禁止放入非 String 物件。pop() 直接回傳 T,呼叫端無需 (String) stack.pop()。Stack<Integer>、Stack<User> 等任意型別。Deque<T> stack = new ArrayDeque<>(),JDK 官方推薦,效能更優(陣列環形緩衝區)。Collections.synchronizedDeque() 或 ConcurrentLinkedDeque。Serializable、Iterable<T>(逆序迭代)等介面增強功能。以 泛型 + LinkedList 實作 Stack<T> 是理解資料結構與 Java 集合框架的優秀練習。核心在於「封裝內部儲存、只暴露棧語義操作」,這正是資料抽象的精髓。實際專案中優先使用 ArrayDeque,但手寫過程能深化對 LIFO、泛型、集合選型的理解。