JAVA容器——Stack(JAVA8) 源码解析

    一 栈简介

    栈是一种常用的线性抽象数据结构,在计算机中应用极为广泛。栈有两个为人熟知的特性,一是进出栈的顺序是先进后出(FILO),即最先进栈的数据最后出栈,当然相对的也有后进先出(LIFO),最后进栈的数据先出栈。另一个是支持两个通用操作:Push:将元素推进栈;Pull:从栈中取出数据。

    栈的操作演示见下图,这里需要注意的是1的位置对应的是栈底,后面再Push的元素所在位置为栈顶,所有对栈的操作,都

是在栈顶操作。

                                                                         图1 栈操作示意图

JAVA容器——Stack(JAVA8) 源码解析_第1张图片

 二 Java栈实现

    Java栈继承自Vector,关系图如下:

                                                                             图2 Java Stack继承关系图

JAVA容器——Stack(JAVA8) 源码解析_第2张图片

    在前面的文章Java Vector源码解析解析中,我们已经对Vector做了介绍,这是一种加锁实现的List。Stack是从Vector中扩展而来, 功能相对要简单许多,下面看看具体实现。

                                                                                图3 Java Stack实现

/**
 *
 * 

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: *

   {@code
 *   Deque stack = new ArrayDeque();}
* * @author Jonathan Payne * @since 1.0 */ public class Stack extends Vector { /** * Creates an empty Stack. */ public Stack() { } /** * Pushes an item onto the top of this stack. */ public E push(E item) { addElement(item); return item; } /** * Removes the object at the top of this stack and returns that * object as the value of this function. */ public synchronized E pop() { E obj; int len = size(); obj = peek(); removeElementAt(len - 1); return obj; } /** * Looks at the object at the top of this stack without removing it * from the stack. */ public synchronized E peek() { int len = size(); if (len == 0) throw new EmptyStackException(); return elementAt(len - 1); } /** * Tests if this stack is empty. * */ public boolean empty() { return size() == 0; } /** * Returns the 1-based position where an object is on this stack. * If the object {@code o} 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 {@code 1}. The {@code equals} * method is used to compare {@code o} 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} * indicates that the object is not on the stack. */ public synchronized int search(Object o) { int i = lastIndexOf(o); if (i >= 0) { return size() - i; } return -1; } }

    由于代码比较少,这里把基本都贴出来了。从继承关系可以看出,Stack就是一个阉割了的Vector。Vector本质上是一个数组,所以Stack也是由数组实现。方法实现的方式如下:

  • Push:将元素添加到栈的最后,也即数组的末尾;
  • Pop:将栈末尾的元素取出并删除;
  • Peek:取出最后一个元素,但不从栈中删除;
  • Search:查找元素距离栈顶的位置;

    这里需要注意的是,上面的操作都是加锁了的,也即是线程安全的,因此Stack本身是一个线程安全的数据类型,当然这也导致了它的性能会受到影响。

    三 小结

    请关注类开头的注释: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:
    Deque stack = new ArrayDeque();

    官方推荐使用双向队列来实现栈,而不是再继续使用Stack这个数据结构。当然Stack的实现方式还是有一定参考价值的。

你可能感兴趣的:(Java,容器)