Stack(栈) 详细介绍(源码分析)

从下面三个层面去分析

1.Stack的简介

2.Stack的数据结构

3.Stack的源码分析

4.Stack的示例

在这篇博客中(进入Vector详细介绍)已经学习Vector,从数据结构这一节,可以看到Stack是继承于Vector的,所以学习Stack更容易学习和理解了,想要学习Stack肯定首先把Vector搞清楚,那么学习起来这一章节就很简单了。只是提供了Stack特有的API,突显了出了栈的特性,Stack这个类也是基于数组数据结构实现的。

1.Stack的简介

Stack 特性:(FILO, First In Last Out,先进后出) 

util工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实现的,这就意味着,Stack也是通过数组实现的而非链表。当然,我们也可以将LinkedList当作栈来使用!在【Vector 详细介绍(源码分析)】已经学习Vector,从下文数据结构这一节,可以看到Stack是继承于Vector的,所以学习Stack更容易学习和理解了,想要学习Stack肯定首先把Vector搞清楚,那么学习起来这一章节就很简单了。只是提供了Stack特有的API,突显了出了栈的特性,Stack这个类也是基于数组数据结构实现的。

2.Stack的数据结构


java.lang.Object
↳     java.util.AbstractCollection<E>
   ↳     java.util.AbstractList<E>
       ↳     java.util.Vector<E>
           ↳     java.util.Stack<E>
public
class Stack<E> extends Vector<E> 

 

Stack的API

Stack区别于常规的集合,Stack是栈,它常用的API如下:

             boolean       empty()
synchronized E             peek()
synchronized E             pop()
             E             push(E object)
synchronized int           search(Object o)

由于Stack和继承于Vector,因此它也包含Vector中的全部API。 

3.Stack的源码分析

package java.util;

/**
 * The <code>Stack</code> class represents a last-in-first-out
 * (LIFO) stack of objects. It extends class <tt>Vector</tt> with five
 * operations that allow a vector to be treated as a stack. The usual
 * <tt>push</tt> and <tt>pop</tt> operations are provided, as well as a
 * method to <tt>peek</tt> at the top item on the stack, a method to test
 * for whether the stack is <tt>empty</tt>, and a method to <tt>search</tt>
 * the stack for an item and discover how far it is from the top.
 * <p>
 * When a stack is first created, it contains no items.
 *
 * <p>A more complete and consistent set of LIFO stack operations is
 * provided by the {@link Deque} interface and its implementations, which
 * should be used in preference to this class.  For example:
 * <pre>   {@code
 *   Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
 *
 * @author  Jonathan Payne
 * @since   JDK1.0
 */
public
class Stack<E> extends Vector<E> {
    /**
     * Creates an empty Stack.
     */
    //构造函数
    public Stack() {
    }

    /**
     * Pushes an item onto the top of this stack. This has exactly
     * the same effect as:
     * <blockquote><pre>
     * addElement(item)</pre></blockquote>
     *
     * @param   item   the item to be pushed onto this stack.
     * @return  the <code>item</code> argument.
     * @see     java.util.Vector#addElement
     */
    // push函数:将元素存入栈顶,push
    public E push(E item) {
        // 将元素存入栈顶。
    // addElement()的实现在Vector.java中
        addElement(item);

        return item;
    }

    /**
     * Removes the object at the top of this stack and returns that
     * object as the value of this function.
     *
     * @return  The object at the top of this stack (the last item
     *          of the <tt>Vector</tt> object).
     * @throws  EmptyStackException  if this stack is empty.
     */
    // pop函数:返回栈顶元素,并将其从栈中删除
    public synchronized E pop() {
        E       obj;
        int     len = size();

        obj = peek();
        // 删除栈顶元素,removeElementAt()的实现在Vector.java中
        removeElementAt(len - 1);

        return obj;
    }

    /**
     * Looks at the object at the top of this stack without removing it
     * from the stack.
     *
     * @return  the object at the top of this stack (the last item
     *          of the <tt>Vector</tt> object).
     * @throws  EmptyStackException  if this stack is empty.
     */
    // peek函数:返回栈顶元素,不执行删除操作
    public synchronized E peek() {
        int     len = size();

        if (len == 0)
            throw new EmptyStackException();
        // 返回栈顶元素,elementAt()具体实现在Vector.java中
        return elementAt(len - 1);
    }

    /**
     * Tests if this stack is empty.
     *
     * @return  <code>true</code> if and only if this stack contains
     *          no items; <code>false</code> otherwise.
     */
    // 栈是否为空
    public boolean empty() {
        return size() == 0;
    }

    /**
     * Returns the 1-based position where an object is on this stack.
     * If the object <tt>o</tt> occurs as an item in this stack, this
     * method returns the distance from the top of the stack of the
     * occurrence nearest the top of the stack; the topmost item on the
     * stack is considered to be at distance <tt>1</tt>. The <tt>equals</tt>
     * method is used to compare <tt>o</tt> to the
     * items in this stack.
     *
     * @param   o   the desired object.
     * @return  the 1-based position from the top of the stack where
     *          the object is located; the return value <code>-1</code>
     *          indicates that the object is not on the stack.
     */
    // 查找“元素o”在栈中的位置:由栈底向栈顶方向数
    public synchronized int search(Object o) {
        // 获取元素索引,elementAt()具体实现在Vector.java中
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }


    //Stack版本id,这个主要用于版本升级控制
    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1224463164541339165L;
}

 (1) Stack实际上也是通过数组去实现的。
       执行push时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。
       执行peek时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。
       执行pop时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。
(2) Stack继承于Vector,Vector拥有的属性和功能,Stack都拥有。

4.Stack的示例

package com.wy.concurrent.collection.stack;

import java.util.Iterator;
import java.util.List;
import java.util.Stack;

/**
 * @author wy
 * @Classname StackTest
 * @Description 栈 (后进先出  基于数组实现和LinkedList中的push和pop方法是有区别的,
 * 看源码可知 stack的push是放在末尾,LinkedList的push方法是把元素放在队头)
 *
 * 限定仅在表尾进行插入和删除操作的线性表
 * 这一端被称为栈顶,相对地,把另一端称为栈底。
 * 向一个栈插入新元素又称作进栈、入栈或压栈
 * 它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素
 * @Date 2019/8/25  15:35
 * @company
 */

public class StackTest {


    public static void main(String[] args) {
        Stack stack = new Stack();
        // 将1,2,3,4,5添加到栈中
        for(int i=1; i<6; i++) {
            stack.push(String.valueOf(i));
        }

        // 遍历并打印出该栈
        iteratorThroughRandomAccess(stack) ;

        // 查找“2”在栈中的位置,并输出
        int pos = stack.search("2");
        System.out.println("the postion of 2 is:"+pos);

        // pop栈顶元素之后,遍历栈
        stack.pop();
        iteratorThroughRandomAccess(stack) ;

        // peek栈顶元素之后,遍历栈
        String val = (String)stack.peek();
        System.out.println("peek:"+val);
        iteratorThroughRandomAccess(stack) ;

        // 通过Iterator去遍历Stack
        iteratorThroughIterator(stack) ;
    }

    /**
     * 通过快速访问遍历Stack
     */
    public static void iteratorThroughRandomAccess(List list) {
        String val = null;
        for (int i=0; i<list.size(); i++) {
            val = (String)list.get(i);
            System.out.print(val+" ");
        }
        System.out.println();
    }

    /**
     * 通过迭代器遍历Stack
     */
    public static void iteratorThroughIterator(List list) {

        String val = null;
        for(Iterator iter = list.iterator(); iter.hasNext(); ) {
            val = (String)iter.next();
            System.out.print(val+" ");
        }
        System.out.println();
    }
}

 

猜你喜欢

转载自blog.csdn.net/crossroads10/article/details/100171440