JDK源码阅读(1):Stack

Stack

version:1.8

Stack为JDK对于先进后出)这一数据结构的实现,其继承Vector类,其操作主要是对Vector类的一些封装。

public class Stack<E> extends Vector<E>

栈主要有三个操作:
push:入栈
pop:出栈
peek:查看栈顶元素

push

源码如下:

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

addElement(E obj)为继承自Vector类的方法,其源码如下:

public synchronized void addElement(E obj) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = obj;
}

Vector内部维持Object数组elementData以存储元素,通过elementCount记录元素个数,ensureCapacityHelper(elementCount + 1)判断是否需要进行扩容。

protected Object[] elementData;
protected int elementCount;

注意到变量modCount,其来自于Vector的父类AbstractList, transient 关键字意味着该变量不参与序列化过程。

protected transient int modCount = 0;

由Vector类中sort()方法中该变量的使用,可推测该变量用于多线程的同步问题。

@SuppressWarnings("unchecked")
@Override
public synchronized void sort(Comparator<? super E> c) {
    final int expectedModCount = modCount;
    Arrays.sort((E[]) elementData, 0, elementCount, c);
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
    modCount++;
}

peek

源码如下:

public synchronized E peek() {
    int     len = size();

    if (len == 0)
        throw new EmptyStackException();
    return elementAt(len - 1);
}

其核心操作为Vector类的elementAt() 方法:

public synchronized E elementAt(int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }
    return elementData(index);
}
@SuppressWarnings("unchecked")
E elementData(int index) {
	return (E) elementData[index];
}

pop

源码如下:

public synchronized E pop() {
    E       obj;
    int     len = size();

    obj = peek();
    removeElementAt(len - 1);

    return obj;
}

pop通过peek获得栈顶元素返回,通过Vector类的removeElementAt(len - 1)方法移除栈顶元素:

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

易知,该方法将数组后半部分元素整体向前移动一位,将最后一位引用指向null,从而移除对该元素的引用,由于栈每次仅移除栈顶元素,故移动该步骤实际未生效。

综上,JDK对栈的实现本质是对数组的封装。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值