首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 進階教程:Stack 棧結構原理與實戰應用

     編輯:Java 相關知識

Stack 類速覽

  • 繼承自 Vector,所有方法同步(線程安全但效能較低)
  • 實現後進先出 (LIFO) 語義
  • JDK 6+ 推薦使用 Deque 介面實現(ArrayDeque 非同步、高效能)
  • 核心操作:push() 入棧、pop() 出棧、peek() 查頂

完整操作示例


Stack<Object> stack = new Stack<>();

// 1. 基本狀態
stack.empty(); // true

// 2. 入棧
stack.push(123);
stack.push("xyz");
stack.push(456);
stack.push("xyz"); // 允許重複

// 3. 查頂(不移除)
stack.peek(); // "xyz" (頂部元素)

// 4. 搜索位置(1-based,頂部為 1)
stack.search(123); // 4 (從頂往下第 4 個)
stack.search("xyz"); // 1 (頂部最近的 "xyz")

// 5. 出棧循環
while (!stack.empty()) {
    System.out.println(stack.pop()); // 依次輸出: "xyz", 456, "xyz", 123
}

核心方法詳解

方法語義異常情況
push(E item)壓入棧頂,返回 item無
pop()移除並返回棧頂空棧拋 EmptyStackException
peek()返回棧頂不移除空棧拋 EmptyStackException
empty()判斷是否為空無
search(Object o)從頂向下找,返回 1-based 索引未找到返回 -1

繼承自 Vector 的額外能力

因繼承 Vector,間接擁有:

  • 隨機訪問:get(index)、set(index, elem)
  • 插入/刪除任意位置:add(index, elem)、remove(index)
  • 同步迭代器
  • 注意:這些操作違反 LIFO 語義,實際開發中應僅使用棧專用方法。

現代替代方案:Deque 介面


// 推薦:ArrayDeque(非同步、雙端、效能優於 Stack)
Deque<String> stack = new ArrayDeque<>();
stack.push("a");      // 入棧
stack.push("b");
stack.peek();         // "b"
stack.pop();          // "b"
stack.isEmpty();      // false
特性StackArrayDeque
線程安全同步方法非同步(單執行緒高效)
擴容機制Vector 擴容 2 倍雙端循環數組,動態擴容
功能豐富度僅 LIFO雙端隊列、棧、隊列三合一
Null 元素允許禁止

典型應用場景

  1. 遞歸轉迭代:手動模擬呼叫棧(如 DFS、表達式求值)。
  2. 括號匹配/語法解析:編譯器、解析器核心邏輯。
  3. 撤銷/重做:編輯器、IDE 操作歷史。
  4. 瀏覽器前進/後退:雙棧實現導航歷史。
  5. 記憶體管理:JVM 方法調用棧、本地變量表。

避坑指南

  • ❌ 不要在多執行緒共享 Stack:雖同步,但複合操作(如 if (!s.empty()) s.pop())非原子。用 ConcurrentLinkedDeque 或加鎖。
  • ❌ 不要依賴 Vector 的隨機訪問方法:違背棧語義,導致代碼難維護。
  • ✅ 新代碼優先用 ArrayDeque:除非需線程安全,否則無理由用 Stack。
  • ✅ 檢查空棧再 pop/peek,或捕獲 EmptyStackException。

總結

Stack 是 LIFO 棧的經典實現,但因同步開銷、Vector 遺留包袱、功能單一,現代 Java 開發中強烈建議使用 ArrayDeque 替代。理解棧原理對掌握遞歸、解析器、記憶體模型等核心計算機科學概念至關重要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved