美文网首页面试
Stack源码分析-通过源码分析Stack不再被推荐使用的原因

Stack源码分析-通过源码分析Stack不再被推荐使用的原因

作者: _风听雨声 | 来源:发表于2020-05-23 18:02 被阅读0次
    Collection家族关系图
    栈是java中比较重要的数据结构,具备后进先出的特点,JDK提供了Stack,由于历史原因,目前Stack已经不被推荐使用了。但依然值得去分析它的源码,以便更好的理解栈的概念,也更好的知道它不再被推荐的原因。其次就是Stack源码非常简短,分析它的源码只需要花一点点的时间就可以。Stack继承自Vector,如需了解Vector,可点击Vector源码分析

    继承关系

    public  class Stack<E> extends Vector<E> 
    

    Stack继承自Vector


    构造方法

        public Stack() {
        }
    

    入栈

        public E push(E item) {
            //调用了父类Vector的addElement(item)
            addElement(item);
            return item;
        }
        
        //父类Vector的addElement(item)
        public synchronized void addElement(E obj) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = obj;
        }
    

    push(E item)调用了父类VectoraddElement(item)方法,说明3点

    • 1.Stack基于Object[]实现
    • 2.线程安全
    • 3.扩容规则和Vector完全一样

    弹栈

        public synchronized E pop() {
            E  obj;
            int  len = size();
            obj = peek();
            removeElementAt(len - 1);
            return obj;
        }
    
        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) {
                System.arraycopy(elementData, index + 1, elementData, index, j);
            }
            elementCount--;
            elementData[elementCount] = null; 
        }
    

    pop()移除栈顶元素,并返回栈顶元素。removeElementAt(int index)是父类Vector的方法。

    • 1.线程安全
      1. 因为是最后一个元素,所以不需要通过System.arraycopy()方法左移,直接将元素数量--,并将最后一个元素置空。

    获取栈顶元素

        public synchronized E peek() {
            int  len = size();
            if (len == 0)
                throw new EmptyStackException();
            return elementAt(len - 1);
        }
    
          public synchronized E elementAt(int index) {
            if (index >= elementCount) {
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
            return elementData(index);
        }
    
        E elementData(int index) {
            return (E) elementData[index];
        }
    

    调用父类VectorelementAt(int index)获取最后一个元素


    总结一下
    通过以上分析可以看到,Stack 继承自Vector。然而,它们是两个不同的数据结构。历史久远,也许是当时是为了快速实现栈的数据结构调用Vector的方法,所以继承了Vector,也因为继承了VectorStack 可以复用Vector的大量方法 。Stack不被推荐使用的原因应该主要有以下3点:

    • 1.继承关系设计不严谨
    • 2.Vector方法加synchronized粒度大,性能上有一定影响
    • 3.有了更好的替代方案ArrayDeque

    相关文章

      网友评论

        本文标题:Stack源码分析-通过源码分析Stack不再被推荐使用的原因

        本文链接:https://www.haomeiwen.com/subject/msziohtx.html