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

Java 集合框架深度剖析:Stack 棧結構實戰應用

     編輯:Java 程式設計入門

Stack 類別概覽

java.util.Stack<E> 繼承自 Vector<E>,實現後進先出(LIFO)棧語義。雖然官方建議改用 Deque 介面(ArrayDeque),但 Stack 仍廣泛存在於歷史程式碼中。

核心操作方法

方法說明異常情況
push(E item)壓入棧頂無
pop()移除並回傳棧頂元素空棧拋出 EmptyStackException
peek()查看棧頂元素不移除空棧拋出 EmptyStackException
empty()判斷棧是否為空回傳 boolean
search(Object o)從棧頂向下搜尋,回傳 1-based 位置未找到回傳 -1

完整實戰範例:員工資料棧操作

package com.test;
import java.util.*;

public class Demo7_3 {
    public static void main(String[] args) {
        Emp emp = new Emp("sa001", "xiaoming", 12.3f);
        Stack<Emp> stack = new Stack<>(); // 建議使用泛型
        stack.push(emp); // 推薦用 push() 而非 add()
        
        // 遍歷棧(注意:棧不支援高效隨機存取)
        for (int i = 0; i < stack.size(); i++) {
            Emp temp = stack.get(i); // 繼承自 Vector 的 get()
            System.out.println("員工姓名:" + temp.getName());
        }
    }
}

// 員工實體類別
class Emp {
    private String empNo;
    private String name;
    private float sal;

    public Emp(String empNo, String name, float sal) {
        this.empNo = empNo;
        this.name = name;
        this.sal = sal;
    }
    // Getter/Setter 省略
    public String getName() { return name; }
    public float getSal() { return sal; }
}

進階應用:表達式求值(中綴轉後綴)

Stack 經典用途:算術表達式解析

public static int evaluatePostfix(String postfix) {
    Stack<Integer> stack = new Stack<>();
    for (String token : postfix.split(" ")) {
        if (isOperator(token)) {
            int b = stack.pop(), a = stack.pop();
            stack.push(applyOperator(a, b, token));
        } else {
            stack.push(Integer.parseInt(token));
        }
    }
    return stack.pop();
}

現代替代方案:Deque > Stack

JDK 官方文件明確建議:

"A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class."

// 推薦寫法
Deque<Emp> stack = new ArrayDeque<>();
stack.push(emp);        // 壓入
Emp top = stack.pop();  // 彈出
Emp peek = stack.peek(); // 查看

ArrayDeque 優勢:非同步(無 synchronized 開銷)、陣列實作記憶體效率高、實作 Deque 介面功能更完整。

常見陷阱與最佳實踐

  • 泛型化:務必使用 Stack<Emp> 避免型別轉換
  • 避免隨機存取:get(i) 效能差,棧語義僅應操作棧頂
  • 執行緒安全:Stack 同步化,多執行緒高併發建議用 ConcurrentLinkedDeque 或自行同步
  • 序列化:Stack 實作 Serializable,但建議轉為 List 序列化

總結

Stack 實現經典 LIFO 語義,適合表達式求值、瀏覽器歷史、遞迴轉迭代等場景。新專案優先選用 ArrayDeque,維護舊代碼時理解其 Vector 繼承特性(同步、動態擴容)即可。掌握棧思維,解決大類遞迴與回溯問題。

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