Jdk8集合源碼解析---java.util.Stack

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的基本介紹完成!。

相關文章
相關標籤/搜索