從jdk里Stack源碼的角度重溫棧的實(shí)現(xiàn)

棧概念

棧是元素的集合, 其中有兩個(gè)原則操作:

  • push, 它添加到集合中
  • pop 則移除最近添加的元素

Push - 添加元素到棧里

下面是push,pop相關(guān)的幾個(gè)關(guān)鍵方法的源碼

public E push(E item) {
    addElement(item);

    return 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);
}


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);
}

push方法調(diào)用addElement(item)往棧里添加元素,elementData是一個(gè)object數(shù)組,addElement方法做的一件事就是把obj元素添加到elementData數(shù)組里,數(shù)組的長(zhǎng)度是固定的,
不斷添加元素肯定會(huì)超數(shù)組的容量,ensureCapacityHelper這個(gè)方法就是確認(rèn)數(shù)組的容量
是否足夠,不夠就進(jìn)行擴(kuò)充。接著看grow這個(gè)方法,進(jìn)行擴(kuò)充,oldCapacity變量記錄舊的數(shù)組長(zhǎng)度,newCapacity等于oldCapacity加上一個(gè)增量,capacityIncrement變量是增量,但默認(rèn)為0,可以在構(gòu)造器中賦值,capacityIncrement為0時(shí),增量等于oldCapacity,newCapacity相當(dāng)于增加了一倍。最后調(diào)用Arrays的copyOf方法把原來的elementData數(shù)組復(fù)制到一個(gè)新的數(shù)組里。

Pop - 移除最近添加的元素

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方法:移除并返回移除棧頂?shù)脑?br> peek方法: 只是返回棧頂?shù)脑?/p>

pop方法是先調(diào)用peek方法獲取棧頂?shù)脑兀谡{(diào)用removeElementAt方法移除。

先看peek方法, 數(shù)組的index是從0開始,棧頂?shù)膇ndex就是len - 1, 最終實(shí)質(zhì)是返回elementData[index]即可。
接著看removeElementAt方法的實(shí)現(xiàn)

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 */
}

這個(gè)方法調(diào)用System.arraycopy()進(jìn)行復(fù)制數(shù)據(jù).

這個(gè)方法是native方法, 先了解一下這個(gè)方法的參數(shù),

/**
 * src : 原數(shù)組
 * srcPos : 原數(shù)組起始位置
 * dest :目標(biāo)數(shù)組
 * destPos : 目標(biāo)數(shù)組起始位置
 * length : 復(fù)制數(shù)組的長(zhǎng)度
 **/
public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

j = 數(shù)組長(zhǎng)度- index(需要移除的位置) - 1;
例如有{ a, b, c, d ,e } 共5個(gè)元素, 要移除c, 這里 j 等于 c 之后的元素個(gè)數(shù),即2個(gè).

調(diào)用System.arraycopy方法時(shí),原數(shù)組和目標(biāo)數(shù)組都是同一個(gè),實(shí)質(zhì)上是把d,e 復(fù)制到原來c, d 的位置上,目標(biāo)數(shù)組為{ a, b, d, e, e}
最后elementCount減1,把數(shù)組elementData最后一個(gè)賦值null, 最終數(shù)組為{ a, b, d, e, null}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 上一章進(jìn)行了ArrayList源碼分析,這一章分析一下另一個(gè)重要的List集合LinkedList。 Linked...
    wo883721閱讀 634評(píng)論 0 0
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,658評(píng)論 0 3
  • 一、棧 1.1 棧的實(shí)現(xiàn) 棧(Stack)是限制僅在表的一端進(jìn)行插入和刪除運(yùn)算的線性表。java沒有棧這樣的數(shù)據(jù)結(jié)...
    yjaal閱讀 1,537評(píng)論 0 1
  • 今天是個(gè)無(wú)聊的一天,今天也是端午節(jié)。 我在度過這一天的時(shí)候,也有一件有趣事。我要開始做飯了。
    奇媽閱讀 359評(píng)論 1 0
  • 在經(jīng)濟(jì)飛速發(fā)展的今天,人們的生活節(jié)奏在不斷地加快,快餐行業(yè)也在這個(gè)時(shí)代應(yīng)運(yùn)而生。 外賣幾乎成為都市...
    一號(hào)小龍女閱讀 397評(píng)論 0 0

友情鏈接更多精彩內(nèi)容