5 手寫Java Stack 核心原始碼
Stack是Java中常用的資料結構之一,Stack具有"後進先出(LIFO)"的性質。
只能在一端進行插入或者刪除,即壓棧與出棧
棧的實現比較簡單,性質也簡單。可以用一個數組來實現棧結構。
- 入棧的時候,只在陣列尾部插入
- 出棧的時候,只在陣列尾部刪除**
我們來看一下Stack的用法 :如下
public static void main(String[] args){ //新建一個棧 Stack<String> stack = new Stack<>(); //分別向棧中新增不同的元素 stack.push("tom"); stack.push("jim"); stack.push("wendy"); stack.push("natasha"); //分別彈棧 System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); }
輸出如下:
natasha wendy jim tom
從輸出可以看到,最後入棧的,最先出棧
下面我們底層用陣列也來實現這樣一個棧,在陣列的尾部插入和刪除。
也就是入棧和出棧。如下圖:

完整的原始碼如下:
public class QStack<E> { //陣列的預設大小為10 private static final int DEFAULT_INIT_CAPACITY = 10; //底層的陣列 private Object[] elements; //棧中的個數 private int size; public QStack() { this(DEFAULT_INIT_CAPACITY); } public QStack(int capacity) { //capacity條件檢查 ,這裡我們直接丟擲異常 if (capacity <= 0) { throw new IllegalArgumentException("capacity <= 0"); } if (capacity > Integer.MAX_VALUE) { throw new IllegalArgumentException("capacity > Integer.MAX_VALUE"); } //新建一個capacity大小的陣列 elements = new Object[capacity]; //初始個數為0 size = 0; } //棧是否為空 public boolean isEmpty() { return size == 0; } //返回棧中的元素個數 public int size() { return size; } //將一個元素壓入棧中 public E push(E e) { //如果棧已滿,進行擴容 if (size >= elements.length) { grow(); } //擴容完後將元素e壓入棧中 elements[size] = e; //別忘了size需要加 1 size++; return e; } //出棧,就是將陣列最後一個元素彈出 public E pop() { //如果棧為空就返回null if (isEmpty()) { return null; } //拿到棧的大小 int len = size(); //把陣列中最後一個元素儲存起來 E e = peek(); //個數別忘了減1 size--; //將最後一個元素置null elements[len - 1] = null; //返回e return e; } //返回最後一個元素 public E peek() { int len = size(); if (len == 0) throw new RuntimeException("stack is empty"); return (E) elements[len - 1]; } //擴容 private void grow() { //將之前的陣列儲存 int oldCapacity = elements.length; Object[] old = elements; //新的陣列大小為原來陣列大小的2倍 int newCapacity = oldCapacity * 2; //再新建一個大小為原來陣列2倍的新陣列 elements = new Object[newCapacity]; //把以前的老的陣列中的元素都移動新陣列中 for (int i = 0; i < oldCapacity; i++) { elements[i] = old[i]; } //釋放以前的記憶體空間 old = null; } }
以上面可知:用陣列實現棧結構,主要需要注意以下 2 點:
- 在陣列的尾部插入和刪除,也就是壓棧和彈棧
- 由於是用陣列實現棧結構,陣列滿的時候,需要擴容
下面我們寫一段測試程式碼來測試,如下:
public static void main(String[] args){ //建立一個棧 QStack<String> stack = new QStack<>(); //分別向棧中壓入4個不同的元素 stack.push("tom"); stack.push("jim"); stack.push("wendy"); stack.push("natasha"); //分別彈棧 System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); }
列印如下:
natasha wendy jim tom