1.Stack的基本介紹java
Stack是一種後進先出(LIFO)的結構,其繼承了Vector的基礎上拓展5個方法push()、pop()、peek()、empty()、search()而來數組
a、push(E):將item推入到棧中,依次加入數組中(數組尾部)。安全
b、pop() :將棧中的最頂一個(數組尾部)item推出,並返回被推出的item數據結構
e、peek():返回棧中最頂(數組尾部)的一個item,但不對其作任何操做函數
d、empty():判斷該棧是否爲空this
e、search(Object):搜索某一個item在該棧中的位置【位置爲離棧頂最近的item與棧頂間距離】線程
PS:雖然Java有提供該類型的數據結構,可是官方推薦使用Deque【雙端隊列】,Deque提供更好的完整性和一致性,應該優先使用。code
Stack基於Vector(Vector的方法用Synchronized修飾的),另外Stack中的pop、peek、search方法夜都是用Synchronized修飾的,因此Stack是線程安全的。對象
2.Stack的類結構繼承
public class Stack<E> extends Vector<E> { ...... }
3.Stack的成員變量
Stack自己類中沒有成員變量,可是由於Stack繼承了Vector類,因此我們得看下Vector的成員變量。
//存儲數據的數組 protected Object[] elementData; //實際存儲的元素個數 protected int elementCount; //擴容的增量值 protected int capacityIncrement;
4.Stack的構造函數
Stack只有一個構造函數。
public Stack() {}
因爲Stack繼承了Vector,因此我們還得看下Vector的構造函數
public Vector() { //默認初始大小是10 this(10); } public Vector(int initialCapacity) { //默認增量爲0 this(initialCapacity, 0); } public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; }
5.Stack的主要方法
5.1添加
public E push(T item);
public E push(E item) { //添加元素 addElement(item); //返回添加的元素 return item; } //該方法是Vector的方法 //該方法使用synchronized修飾了,因此是線程安全的 public synchronized void addElement(E obj) { //修改次數加一 modCount++; //判斷是否須要擴容 ensureCapacityHelper(elementCount + 1); //將被添加的對象放置在elementCount++位置,即size+1 elementData[elementCount++] = obj; } //該方法是Vector的方法 private void ensureCapacityHelper(int minCapacity) { //判斷是否須要擴容:size+1是否大於當前數組的長度 if (minCapacity - elementData.length > 0) //擴容 grow(minCapacity); } //該方法是Vector的方法 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; //capacityIncrement爲每次擴容的增量 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); }
經過查看源碼咱們發現Stack的底層數據結構也是數組,能夠動態擴容,和ArrayList的底層數據結構是同樣的,可是擴容方法有區別,ArrayList通常是擴容至1.5倍,而Stack有個擴容增量值,若是該增量值大於零,新容量值就等於就容量值加上增量值,不然即爲舊容量值的兩倍。
5.2.public synchronized E peek();返回棧頂(數組尾部)的元素,但不將其從棧中刪除。
public synchronized E peek() { //獲取當前數組中元素個數 int len = size(); if (len == 0) throw new EmptyStackException(); //返回數組尾部元素,因此後進先出 return elementAt(len - 1); } //Vector中的方法 public synchronized E elementAt(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } return elementData(index); } //Vector中的方法 E elementData(int index) { return (E) elementData[index]; }
5.3.public synchronized E pop():返回棧頂(數組尾部)的元素,並將其從棧中刪除。
public synchronized E pop() { E obj; int len = size(); //獲取數組尾部元素 obj = peek(); //將尾部元素刪除 removeElementAt(len - 1); return obj; }
5.4.public synchronized int search(Object o);
public synchronized int search(Object o) { //返回數組中最後一個元素爲o的下角標 int i = lastIndexOf(o); if (i >= 0) { //返回棧頂(數組尾部)與該元素的距離 return size() - i; } return -1; }
至此,java.util.Stack的基本介紹完成!。