zoukankan      html  css  js  c++  java
  • Java源码阅读Stack

    Stack(栈)实现了一个后进先出(LIFO)的数据结构。该类继承了Vector类,是通过调用父类Vector的方法实现基本操作的。

    Stack共有以下五个操作:

    put:将元素压入栈顶。

    pop:弹出栈顶元素(返回栈顶元素,并删除)。

    peek:取栈顶元素(不删除)。

    empty:判断栈是否为空。

    search:搜索一个元素是否在栈里,并返回其到栈顶的距离。

    public class Stack<E> extends Vector<E> {
       
        public Stack() {
        }
    
        public E push(E item) {
            addElement(item);
    
            return item;
        }
    
        public synchronized E pop() {
            E       obj;
            int     len = size();
    
            obj = peek();
            removeElementAt(len - 1);
    
            return obj;
        }
    
        public synchronized E peek() {
            int     len = size();
    
            if (len == 0)
                throw new EmptyStackException();
            return elementAt(len - 1);
        }
    
        public boolean empty() {
            return size() == 0;
        }
    
        public synchronized int search(Object o) {
            int i = lastIndexOf(o);
    
            if (i >= 0) {
                return size() - i;
            }
            return -1;
        }
    
        /** use serialVersionUID from JDK 1.0.2 for interoperability */
        private static final long serialVersionUID = 1224463164541339165L;
    }

    在之前源码阅读中我们知道vector是通过数组实现的。这里Stack又是通过Vector实现的,接下来我们挨个看其方法的实现。首先明确一点,stack是线程安全的。

    (1)put

    put方法并没有被synchronized修饰,因为该方法里面只有一条语句,调用Vector的addElement(item)方法,意思是在数组末尾插入一个元素,而addElement是被synchronized修饰的,所以put方法也是线程安全的。

    (2)peek

    首先获取数组的size,若为0,则报EmptyStackException异常。然后返回数组的最后一个元素。

    (3)pop

    先通过peek获取栈顶元素(数组最后一个元素),然后调用removeElementAt方法删除栈顶元素,最后返回之前获取的栈顶元素。

    (4)search

    通过lastIndexOf方法从后往前遍历找到匹配元素并获取所在位置的索引号i,然后通过size() - i返回其深度(到栈顶的距离)。若没有找到则返回-1。

    总结

    其实栈这种数据结构可以简单的通过一个数组进行模拟。

    下面是我自己用1个数组实现的可扩容的栈MyStack

    package com.ouym.test;
    
    import java.util.Arrays;
    import java.util.EmptyStackException;
    
    public class MyStack<E> {
    
        private Object[] elementData;
        private int elementCount; //表示当前栈存放的数据量
    
        public MyStack() {
            this(10);
        }
    
        public MyStack(int initialCapacity) {
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity:"+initialCapacity);
            
            elementData = new Object[initialCapacity];
        }
    
        //扩容栈,扩容方式:新容量=旧容量*2
        private void grow() {
    
            int capacity = elementData.length;
            capacity = capacity << 1;
            if (capacity < 0) {
                throw new OutOfMemoryError();
            }
            elementData = Arrays.copyOf(elementData, capacity);
    
        }
    
        public E put(E item) {
            if (elementCount == elementData.length) {
                grow();
            }
            elementData[elementCount++] = item;
            return item;
        }
    
        @SuppressWarnings("unchecked")
        public E peek() {
            if (empty()) {
                throw new EmptyStackException();
            }
            return (E) elementData[elementCount - 1];
        }
    
        public E pop() {
            E item = peek();
            elementData[elementCount--] = null;
            return item;
        }
    
        public boolean empty() {
            return elementCount == 0;
        }
        
        public int size(){
            return elementCount;
        }
    
        public int search(E item) {
            if (item == null) {
                for (int i = elementCount - 1; i >= 0; i--)
                    if (elementData[i] == null)
                        return i;
            } else {
                for (int i = elementCount - 1; i >= 0; i--) {
                    if (item.equals(elementData[i])) {
                        return elementCount - i;
                    }
                }
            }
    
            return -1;
        }
    
    }

    --------------------THE END--------------------

  • 相关阅读:
    查询job的几个语句
    fdisk与parted分区
    升级时针对Source oracle home 不存在解决办法
    oracle常用视图v$mystat v$sesstat v$sysstat v$statname v$thread v$ parameter v$session v$process
    x$ksppi与x$ksppcv查询隐藏参数
    查询表空间及已使用情況的SQL语句
    通过系统进程查找sql语句
    RAC日常维护命令
    创建ASM实例及ASM数据库(转载)
    安装数据库软件,节点未显示
  • 原文地址:https://www.cnblogs.com/ouym/p/8888933.html
Copyright © 2011-2022 走看看