Stack

作者: Alsan_L3 | 来源:发表于2022-02-25 10:25 被阅读0次

    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这个类。

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

    相关文章

      网友评论

        本文标题:Stack

        本文链接:https://www.haomeiwen.com/subject/txrxrrtx.html