棧是java中比較重要的數(shù)據(jù)結構,具備后進先出的特點,JDK提供了Stack,由于歷史原因允坚,目前Stack已經(jīng)不被推薦使用了匹层。但依然值得去分析它的源碼隙笆,以便更好的理解棧的概念,也更好的知道它不再被推薦的原因升筏。其次就是Stack源碼非常簡短撑柔,分析它的源碼只需要花一點點的時間就可以。Stack繼承自Vector您访,如需了解Vector,可點擊Vector源碼分析
繼承關系
public class Stack<E> extends Vector<E>
Stack
繼承自Vector
構造方法
public Stack() {
}
入棧
public E push(E item) {
//調(diào)用了父類Vector的addElement(item)
addElement(item);
return item;
}
//父類Vector的addElement(item)
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
push(E item)
調(diào)用了父類Vector
的addElement(item)
方法铅忿,說明3點
- 1.
Stack
基于Object[]實現(xiàn)
- 2.線程安全
- 3.擴容規(guī)則和
Vector
完全一樣
彈棧
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
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;
}
pop()移除棧頂元素,并返回棧頂元素灵汪。removeElementAt(int index)
是父類Vector
的方法檀训。
- 1.線程安全
- 因為是最后一個元素,所以不需要通過
System.arraycopy()
方法左移享言,直接將元素數(shù)量--峻凫,并將最后一個元素置空。
- 因為是最后一個元素,所以不需要通過
獲取棧頂元素
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
調(diào)用父類Vector
的elementAt(int index)
獲取最后一個元素
總結一下
通過以上分析可以看到览露,Stack
繼承自Vector
荧琼。然而,它們是兩個不同的數(shù)據(jù)結構。歷史久遠铭腕,也許是當時是為了快速實現(xiàn)棧的數(shù)據(jù)結構調(diào)用Vector
的方法银择,所以繼承了Vector
,也因為繼承了Vector
累舷,Stack
可以復用Vector
的大量方法 浩考。Stack
不被推薦使用的原因應該主要有以下3點:
- 1.繼承關系設計不嚴謹
- 2.
Vector
方法加synchronized
粒度大,性能上有一定影響 - 3.有了更好的替代方案
ArrayDeque