Java 集合深入理解 :stack源码分析,及如何利用vector实现栈

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 集合深入理解 :stack源码分析,及如何利用vector实现栈相关的知识,希望对你有一定的参考价值。

Java 集合深入理解 (四) :线程安全的集合 Vector
前言
stack 是继承自Vector 的,那就说明 stack是基于vector做的实现;从stack 从1.0被开发出来,可能为了快速的推出一些基本的数据结构操作,所以推出了一些比较粗糙的类。比如,Vector、Stack、Hashtable等。这些类中的一些方法加上了 synchronized 关键字,容易给一些初级程序员在使用上造成一些误解!而且在之前的几个版本中,性能还不怎么好,但从学数据结构的角度,还是值得我们去了解它

先从一个小例子来解读这个

public static void main(String[] args) {
		Stack<String> stack = new Stack<String>();
		for(int i=0;i<5;i++) {
			stack.push(i+"");
			System.out.print(i+"");
		}
		System.out.println("");
		System.out.println("");
		for(int i=0;i<5;i++) {
			System.out.print(stack.pop());
		}
	}
打印结果
01234
43210

从我写的小例子明显就看出先进后出的概念。
这也是在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在各个存储区或寄存器 以及jvm中大量的都使用了这样的概念

实现原理

栈的实现原理
在这里插入图片描述
stack如何实现栈的

在这里插入图片描述

全篇注释

/**
*<code>堆栈</code>类表示后进先出(后进先出)一堆物体。它用五个允许向量作为堆栈处理的操作。照常提供了<tt>推送</tt>和<tt>弹出</tt>操作,以及方法在堆栈的顶部项目上进行查看,这是一种测试方法堆栈是否为空,以及搜索的方法
*一个项目的堆栈,并发现它离顶部有多远。首次创建堆栈时,它不包含任何项。
*<p>需要一套更完整、更一致的后进先出堆栈操作由{@link Deque}接口及其实现提供
*应优先于此类使用。例如:
*<pre>{@代码
*Deque<Integer>stack=new ArrayDeque<Integer>();}</预处理>
 *
 * @author  Jonathan Payne
 * @since   JDK1.0
 */

1.堆栈 的作用后进先出(后进先出)一堆物体。
2.它用五个允许向量作为堆栈处理的操作,也就是push pop peek empty search 方法。
3.但是如果真的要使用,优先使用的还是ArrayDeque

构造方法

默认容量为10,在初始化容量构造方法中直接new对象。

   public Vector() {
        this(10);
    }

push方法

将数据推送到栈的顶部,调用的是Vector 的addElement 进行推送到堆栈顶部
Vector 的addElement 方法
addElement 这个方法的实现 和arraylist中的add方法的很像
通过 modCount 记录修改的值
ensureCapacityHelper 去扩容(栈默认是没有设置capacityIncrement 的方法)
这里的扩容 和 arraylistt,还是有不同的算法, 构造没有设定容量的容量增加大小,则直接扩容两倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);

/**
*将项目推送到堆栈顶部。这确实效果与:<blockquote><pre>
*添加元素(项)</pre></blockquote>
*@param item要推送到这个堆栈上的项目。
*@返回<code>e</code>参数。
*@see java.util.Vector#addElement

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

        return item;
    }

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

pop和peek方法

pop和peek从字面意思去理解 就是 离开和偷看 ,
所以pop方法移除此堆栈顶部的对象并返回对象作为此函数的值
peek方法 查看此堆栈顶部的对象而不删除它从堆栈中
看两个方法的实现很简单, 也是拿出最后一个 元素的index指针,去找到最后一个元素,然后把元素删除掉

pop 相对于peek 方法 多调用了removeElementAt方法。

  /**
*移除此堆栈顶部的对象并返回对象作为此函数的值。@返回此堆栈顶部的对象(最后一项)<tt>矢量(对象)。
*如果此堆栈为空,@抛出EmptyStackException。
*/
    public synchronized E pop() {
        E       obj;
        int     len = size();

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

        return obj;
    }
/**
*查看此堆栈顶部的对象而不删除它从堆栈中。@返回此堆栈顶部的对象(最后一项)
*<tt>矢量(对象)。
*如果此堆栈为空,@抛出EmptyStackException。
*/
    public synchronized E peek() {
        int     len = size();

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

empty 和search方法

这两个方法很简单,通过size去判断数据是否存在,以及查找 对象在那个位置
size方法 都在vector中的。

 /**
     * 测试此堆栈是否为空。
     *
     * @return  <code>true</code> if and only if this stack contains
     *          no items; <code>false</code> otherwise.
     */
    public boolean empty() {
        return size() == 0;
    }
    /**
     *返回对象在此堆栈上的基于1的位置。如果对象<tt>o</tt>作为此堆栈中的项出现,则方法返回到堆栈顶部的距离
     *最靠近堆栈顶部的事件;最上面的项目堆栈被认为位于距离<tt>1</tt>处。<tt>等于</tt>方法用于比较此堆栈中的项。
     * @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.
     */
    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

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

其他方法

在stack实现中只包含上面的方法,但是像vector中的add 方法,迭代器, remove indexof AbstractList 中的 subList 这些都是可以使用的,肯定不是只有上面的方法

总结

stack基础的数据结构,用来理解基本数据结构还是很有用的,但是并不推荐使用
推荐使用ArrayDeuqe或者LinkedList的实现代替,并且效率是大于stack。

以上是关于Java 集合深入理解 :stack源码分析,及如何利用vector实现栈的主要内容,如果未能解决你的问题,请参考以下文章

Java 集合深入理解 :优先队列(PriorityQueue)之源码解读,及最小顶堆实现研究

Java 集合深入理解 :ArrayList源码解析,及动态扩容机制

Java集合Stack源码深入解析

Java 集合深入理解 (十三) :ArrayDeque实现原理研究,及动态扩容双端队列和单队列和栈比较

深入Java基础--哈希表HashMap应用及源码详解

Java 集合深入理解 :HashMap之实现原理及hash碰撞