源码分析

Stack

2022-02-25  本文已影响0人  Alsan_L3

Stack,中文名:栈,这个词在开发过程中经常会提到,但是,实际开发中用到Stack这个类就很少了,我们用的最多的还是ArrayList和HashMap。

那么,我们什么情况下会用到这个类呢,我们来看看这个类是如何实现的,Stack的源码很短,大家可以很快就看完,我们先来看下类的声明:

public class Stack<E> extends Vector<E> {}

这里可以看到Stack继承自Vector,那么Vector又是什么呢,我们继续看:

public class Vector<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{}

是不是看着有点眼熟,对的,我们之前分析过ArrayList的实现,ArrayList跟Vector继承和实现的接口是一样的,所以说Vector(Stack)也是一个List,拥有List的一切特性。
另外,Stack栈我们都知道他的定义:先进后出。那么他是怎么实现先进后出的呢,接下来我们来看Stack的几个方法:

boolean empty() //测试栈是否为空
Object peek( )//查看栈顶部的对象,但不从栈中移除它
Object pop( )//移除栈顶部的对象,并作为此函数的值返回该对象
Object push(Object element)//把项压入栈顶部
int search(Object element)//返回对象在栈中的位置,以 1 为基数

关注pop和push两个方法,实现了栈的先进后出,我们来看push的实现:

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

        return item;
    }

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

可以看出里面的实现也是基于数组完成的,与add调用的是同一个方法,都是在数组后面增加一个元素;接着我们来看pop方法:

    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; /* to let gc do its work */
    }

首先通过peek拿到栈顶元素,然后调用removeElementAt(len-1)方法去移除最后一个元素,移除操作也是通过数组拷贝实现的。

前面我们知道,Stack实现了List的所有特性,并且里面都是通过数组实现的,除了上面拥有栈先进后出的特性外,它与ArrayList还有什么区别呢,我们可以从源码中方法声明可以看到,Vector和Stack的方法都带了synchronized关键字,说明Stack是线程安全的。之前我们分析过ArrayList,它不是线程安全的,所以以后如果有需求要用到线程安全的List或者要实现先进后出的特性,都可以用Stack这个类。

好了,今天内容就到这里了,明天继续。

上一篇下一篇

猜你喜欢

热点阅读