棧是一種后進先出的數據結構。在它之上,主要有三種操作:
(1)判斷棧是否為空——empty();
(2)在棧頂添加一個元素——push(E);
(3)刪除并返回棧頂元素——pop()。
在Java類庫中,Stack類實現了棧,它繼承自Vector類:
public class Stack extends Vector于是,Stack用數組保存元素:
protected Object[] elementData;用一個整數記錄棧中元素的個數:
protected int elementCount;接下來看看棧的三種操作在Stack中是如何實現的。
1.
empty()?方法實現如下:
public boolean empty() {
return size() == 0;
}
size()方法是在Vector中定義的方法,具體定義如下:
public synchronized int size() {
return elementCount;
}
它返回棧中元素的個數,也就是說,如果棧中元素個數為0,棧就為空。
2.push(E element)方法實現如下:
public E push(E item) {
addElement(item);
return item;
}
它調用addElement(E)方法實現向棧中添加元素,addElement(E)方法實現如下:
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
只需要關注方法的最后一行:
elementData[elementCount++] = obj;
它將元素添加到之前數組中已有元素的后面并把元素個數加1,這正是棧的push操作需要的。
3.pop()方法實現如下:public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
前面已經知道size()返回棧中元素的個數,于是len等于elementCount;peek()是Stack中的另一個方法,用于返回棧頂元素;removeElementAt(int)是Vector中定義的方法,刪除指定位置元素。
peek()實現如下:
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
peek()方法又調用Vector中定義的方法elementAt(int)返回棧頂元素,elementAt(int)的實現如下:
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
elementAt(int)方法又調用elementData(int)方法,elementData(int)方法實現如下:
E elementData(int index) {
return (E) elementData[index];
}
原來,peek()方法實際上就是通過elementData[len-1]返回棧頂元素的。
接下來看removeElementAt(int)方法:
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
pop()中傳給removeElementAt(int)的參數是len-1,
也就是elementCount-1,也就是說,removeElementAt(int)中的j=0,于是removeElementAt(int)方法直接執行到:
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */這兩行通過先把棧中元素數量減1,然后把之前的棧頂元素設置為null使之被垃圾收集器回收達到刪除棧頂元素的目的。