供自己鞏固集合知識時寫的筆記,不會對所有的內容都介紹
棧(Stack)是一種后進先出(LIFO:Last In First Out)的數據結構
Stack
只有入棧和出棧的操作:
- 把元素壓棧:
push(E)
; - 把棧頂的元素“彈出”:
pop()
; - 取棧頂元素但不彈出:
peek()
。
有的人在使用Stack
時會發現,Stack
沒有單獨的接口。因為有個遺留類名字就叫Stack
,出於兼容性考慮,所以沒辦法創建Stack
接口。
Stack的作用
Stack在計算機中使用非常廣泛,JVM在處理Java方法調用的時候就會通過棧這種數據結構維護方法調用的層次。例如:
static void main(String[] args) {
foo(123);
}
static String foo(x) {
return "F-" + bar(x + 1);
}
static int bar(int x) {
return x << 2;
}
JVM會創建方法調用棧,每調用一個方法時,先將參數壓棧,然后執行對應的方法;當方法返回時,返回值壓棧,調用方法通過出棧操作獲得方法返回值。
因為方法調用棧有容量限制,嵌套調用過多會造成棧溢出,即引發StackOverflowError
:
public class Main {
public static void main(String[] args) {
increase(1);
}
static int increase(int x) {
return increase(x) + 1;
}
}
我們再來看一個Stack
的用途:對整數進行進制的轉換就可以利用棧。
例如,我們要把一個int
整數12500
轉換為十六進制表示的字符串:
先我們准備一個空棧:
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└───┘
然后計算12500÷16=781…4,余數是4
,把余數4
壓棧:
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ 4 │
└───┘
然后計算781÷16=48…13,余數是13
,13
的十六進制用字母D
表示,把余數D
壓棧:
│ │
│ │
│ │
│ │
│ │
│ D │
│ │
│ 4 │
└───┘
然后計算48÷16=3…0,余數是0
,把余數0
壓棧:
│ │
│ │
│ │
│ 0 │
│ │
│ D │
│ │
│ 4 │
└───┘
最后計算3÷16=0…3,余數是3
,把余數3
壓棧:
│ │
│ 3 │
│ │
│ 0 │
│ │
│ D │
│ │
│ 4 │
└───┘
當商是0
的時候,計算結束,我們把棧的所有元素依次彈出,組成字符串30D4
,這就是十進制整數12500
的十六進制表示的字符串。