對於Stack這個集合類,由類繼承關係可知是Vector的子類,根據push入棧方法跟蹤程式碼,可知Vector是一個執行緒安全的類(高併發場景下使用,那可能不是一個好的選擇)
看到這裡,顯然可以得知Stack入棧出棧的大致原理,就是Vector的elementData物件陣列
,用來儲存資料,入棧時依次存放,出棧時倒序從陣列中取出即可
在單向連結串列反轉列印這樣的場景中,我們可以很自然地想到使用遞迴來實現,相比遞迴我們可以使用Stack類依次將單向連結串列的Node節點
存放至Stack的物件陣列中,然後反向出棧取出即可。
public void reversePrint(Node node) {
Stack<Node> stack = new Stack<>();
while (node != null) {
stack.push(node);
node = node.next;
}
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
public void recursion(Node node) {
if (node.next != null) {
recursion(node.next);
}
System.out.println(node);
}
顯然,在連結串列中節點元素較多的場景下,使用Stack的方案明顯所需的memory更少。我們可以根據這個簡單的示例,在遞迴場景下優先考慮Stack方案的可能性~(使用了資料結構來最佳化:方法呼叫所需要的記憶體空間)
當程式執行一個方法時,它會在呼叫棧上建立一個新的棧幀(Stack Frame)。這個棧幀包含了執行該方法所需的所有資訊。當方法執行完畢並準備返回時,它的棧幀會從呼叫棧中彈出,控制權返回給呼叫者。
對於遞迴方法,每次遞迴呼叫都會建立一個新的棧幀,並將其推入呼叫棧中。如果遞迴呼叫過深,即呼叫棧中的棧幀數量超過了系統或JVM(Java虛擬機器)等環境為呼叫棧分配的記憶體限制,就會發生棧溢位錯誤(StackOverflowError)。