zoukankan      html  css  js  c++  java
  • Stack&Vector源码分析 jdk1.6

    参照:http://www.cnblogs.com/tstd/p/5104099.html

    Stack(Fitst In Last Out)

    1、定义

    public  class Stack<E> extends Vector<E> {
    public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

    Vector是List的一个实现类,基于数组。扩容为*2。其功能和实现代码和ArrayList基本一样,Vector是线程安全的,ArrayList不是。应为Vector在每一个方法上都加了synchronized,但是效率不高,不推荐。

    更好的方案,Collections.synchronizedList()。

    2、Stack && Vector底层存储

    // 底层使用数组存储数据
        protected Object[] elementData;
        // 元素个数
        protected int elementCount ;
        // 自定义容器扩容递增大小
        protected int capacityIncrement ;
    
        public Vector( int initialCapacity, int capacityIncrement) {
            super();
            // 越界检查
            if (initialCapacity < 0)
                throw new IllegalArgumentException( "Illegal Capacity: " +
                                                   initialCapacity);
            // 初始化数组
            this.elementData = new Object[initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }
     
        // 使用synchronized关键字锁定方法,保证同一时间内只有一个线程可以操纵该方法
        public synchronized boolean add(E e) {
            modCount++;
           // 扩容检查
           ensureCapacityHelper( elementCount + 1);
            elementData[elementCount ++] = e;
            return true;
        }
     
        private void ensureCapacityHelper(int minCapacity) {
            // 当前元素数量
            int oldCapacity = elementData .length;
            // 是否需要扩容
            if (minCapacity > oldCapacity) {
               Object[] oldData = elementData;
               // 如果自定义了容器扩容递增大小,则按照capacityIncrement进行扩容,否则按两倍进行扩容(*2)
               int newCapacity = (capacityIncrement > 0) ?
                  (oldCapacity + capacityIncrement) : (oldCapacity * 2);
               if (newCapacity < minCapacity) {
                  newCapacity = minCapacity;
               }
               // 数组copy
                elementData = Arrays.copyOf( elementData, newCapacity);
           }
        }

    3、peek()获取栈顶的对象

    /**
         * 获取栈顶的对象,但是不删除
         */
        public synchronized E peek() {
            // 当前容器元素个数
            int   len = size();
         
            // 如果没有元素,则直接抛出异常
            if (len == 0)
               throw new EmptyStackException();
            // 调用elementAt方法取出数组最后一个元素(最后一个元素在栈顶)
            return elementAt(len - 1);
        }
     
        /**
         * 根据index索引取出该位置的元素,这个方法在Vector中
         */
        public synchronized E elementAt(int index) {
            // 越界检查
            if (index >= elementCount ) {
               throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
           }
    
            // 直接通过数组下标获取元素
            return (E)elementData [index];
        }

    4、pop()弹栈

    /**
         * 弹栈,获取并删除栈顶的对象
         */
        public synchronized E pop() {
            // 记录栈顶的对象
           E      obj;
            // 当前容器元素个数
            int   len = size();
    
           // 通过peek()方法获取栈顶对象
           obj = peek();
           // 调用removeElement方法删除栈顶对象
           removeElementAt(len - 1);
    
           // 返回栈顶对象
            return obj;
        }
    
        /**
         * 根据index索引删除元素
         */
        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) {
               // 进行数组移动,中间删除了一个,所以将后面的元素往前移动(这里直接移动将index位置元素覆盖掉,就相当于删除了)
               System. arraycopy(elementData, index + 1, elementData, index, j);
           }
            // 容器元素个数减1
            elementCount--;
            // 将容器最后一个元素置空(因为删除了一个元素,然后index后面的元素都向前移动了,所以最后一个就没用了 )
            elementData[elementCount ] = null; /* to let gc do its work */
        }

    5.push(E item)——压栈(入栈)

    /**
         * 将对象添加进容器并返回
         */
        public E push(E item) {
           // 调用addElement将元素添加进容器
           addElement(item);
           // 返回该元素
            return item;
        }
    
        /**
         * 将元素添加进容器,这个方法在Vector中
         */
        public synchronized void addElement(E obj) {
            modCount++;
           // 扩容检查
           ensureCapacityHelper( elementCount + 1);
           // 将对象放入到数组中,元素个数+1
            elementData[elementCount ++] = obj;
        }

    6.search(Object o)——返回对象在容器中的位置,栈顶为1

    /**
         * 返回对象在容器中的位置,栈顶为1
         */
        public synchronized int search(Object o) {
            // 从数组中查找元素,从最后一次出现
            int i = lastIndexOf(o);
    
            // 因为栈顶算1,所以要用size()-i计算
            if (i >= 0) {
               return size() - i;
           }
            return -1;
        }
  • 相关阅读:
    pyhon简单比较文本相似度的方法
    MongoDB数据的导入、导出、备份与恢复
    django实现注册、登录小系统
    nginx+uwsgi部署django的简单介绍
    python操作Excel的几种方式
    Python的Pexpect的简单使用
    JVM之类加载
    Java中的绑定
    JVM之GC
    JVM之内存管理
  • 原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8516877.html
Copyright © 2011-2022 走看看