1、棧初識
Stack類是jdk中java.util包下的一個類。其方法有
棧是一種用於存儲數據的簡單數據結構,與普通的線性表不同,線性表是先進先出,即FIFO,但是棧是先進後出,即FILO。我們一般只能對棧頂元素進行操作。
2、Stack類的繼承關係接口實現
Stack繼承了Vector類,Vector類又實現了List接口。
3、Stack類的特點
3.1 構造函數
從源碼中瞭解到,Stack類只有一個無參構造函數
/**
* Creates an empty Stack.
*/
public Stack() {
}
所以,我們無法像ArrayList或者HashMap那樣,初始化指定棧的容量大小。那麼棧的初識化容量是多少呢?什麼時候進行擴容呢?擴容的默認容量是多少呢?
由於Stack繼承了Vector類,在Vector類的源碼中可以看出:
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector() {
this(10);
}
可以看到,如果我們不指定vector的容量大小,那麼初始化的默認容量就是10。這和ArrayList的初始化容量一致。
那麼何時擴容呢?Stack的push()方法如下
public E push(E item) {
addElement(item);
return item;
}
Stack直接調用了Vector類的addElement(E item)方法
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
可以看到,是在計算插入數據後容量大小與原來容量大小做比較,除非棧滿了,纔會進行擴容。擴容調用的就是grow(minCapacity)
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
可以看到,如果沒有指定每次擴容的容量大小,默認的新容量將會是兩倍的舊容量。
這一點與我們熟知的ArrayList的擴容大小不一樣,ArrayList的新容量大小是舊容量加上舊容量的值的值右移一位。即
3.2 pop與peek
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
這兩個方法都加鎖了,是線程安全的操作。
pop操作當中包含了peek操作,pop是返回棧頂元素,並將該元素從棧中刪除。而peek只返回棧頂元素,不刪除。
棧的底層數據結構用的是數組。
4、應用
棧的一些應用主要就是運用其先進後出的特性,比較典型的應用就是表達式計算,包括中綴表達式、後綴表達式以及符號匹配等等。
先留個坑,有空再填。