zoukankan      html  css  js  c++  java
  • jdk1.8-stack 栈源码分析

    一:类的继承关系
    UML图:

    类的继承关系:
    public
    class Stack<E> extends Vector<E>
    分析:栈的继承关系很简单,就是继承了Vector,那么我们可以猜测栈操作大部分应该是线程安全的。

    二:类的成员属性
    栈这个类除了一个版本号外,没有其它成员属性


    三:看下构造方法
    构造方法就一个,无参构造方法,什么也没做
    /**
    * Creates an empty Stack.
    */
    public Stack() {
    }


    四:主要方法
    1.push()方法
    /**
    * Pushes an item onto the top of this stack. This has exactly
    * the same effect as:
    * <blockquote><pre>
    * addElement(item)</pre></blockquote>
    *
    * @param item the item to be pushed onto this stack.
    * @return the <code>item</code> argument.
    * @see java.util.Vector#addElement
    */
    public E push(E item) {
    //调用父类vector的addElement()方法
    addElement(item);

    return item;
    }
    分析:往栈里压入一个元素用push方法,每次往栈的顶部压入元素。addElement()是抽象父类vector方法,我们在vector里已经分析过。从这里我们可以知道,栈的底层数组结构也是数组。


    2.pop()方法
    /**
    * Removes the object at the top of this stack and returns that
    * object as the value of this function.
    *
    * @return The object at the top of this stack (the last item
    * of the <tt>Vector</tt> object).
    * @throws EmptyStackException if this stack is empty.
    */
    public synchronized E pop() {
    E obj;
    //栈的长度
    int len = size();

    //栈顶部的元素值(也就是数组最后一个元素值)
    obj = peek();
    //栈元素减1
    removeElementAt(len - 1);

    //返回顶部元素
    return obj;
    }
    分析:删除栈顶部的对象,并将该对象作为函数值返回
    这里我们继续看下removeElementAt()方法,   peik()方法单独讲
    /**
    * Deletes the component at the specified index. Each component in
    * this vector with an index greater or equal to the specified
    * {@code index} is shifted downward to have an index one
    * smaller than the value it had previously. The size of this vector
    * is decreased by {@code 1}.
    *
    * <p>The index must be a value greater than or equal to {@code 0}
    * and less than the current size of the vector.
    *
    * <p>This method is identical in functionality to the {@link #remove(int)}
    * method (which is part of the {@link List} interface). Note that the
    * {@code remove} method returns the old value that was stored at the
    * specified position.
    *
    * @param index the index of the object to remove
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    */
    public synchronized void removeElementAt(int index) {
    //修改次数加1
    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 + 1位置开始,向左移动一个位置,移动的个数为j
    System.arraycopy(elementData, index + 1, elementData, index, j);
    }
    //数组实际元素减1
    elementCount--;
    //数组最后一个元素置为null,等待gc回收
    elementData[elementCount] = null; /* to let gc do its work */
    }
    分析:传进来len -1,栈顶部元素下标,即数组最后一个元素位置。
    数组删除当前元素通过将当前元素以后的所有元素往左移动一位,然后末尾元素置为null而达到的。
    只不过这里删除的元素就是最后一位,所以j=0,并不需要再移动元素而已了。

    3.peek()方法
    /**
    * Looks at the object at the top of this stack without removing it
    * from the stack.
    *
    * @return the object at the top of this stack (the last item
    * of the <tt>Vector</tt> object).
    * @throws EmptyStackException if this stack is empty.
    */
    public synchronized E peek() {
    int len = size();

    if (len == 0)
    throw new EmptyStackException();
    //根据索引从数组里取值,elementAt是调用父类Vector的方法
    return elementAt(len - 1);
    }
    分析:栈的peek()方法,其实就是返回栈顶部的元素值,即数组末尾元素值。
    peek()方法只是返回下标的值,但并不删除该元素,删除是通过上面的removeElementAt()方法。

    /**
    * Returns the component at the specified index.
    *
    * <p>This method is identical in functionality to the {@link #get(int)}
    * method (which is part of the {@link List} interface).
    *
    * @param index an index into this vector
    * @return the component at the specified index
    * @throws ArrayIndexOutOfBoundsException if the index is out of range
    * ({@code index < 0 || index >= size()})
    */
    public synchronized E elementAt(int index) {
    if (index >= elementCount) {
    throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }

    return elementData(index);
    }
    分析:这个方法就是根据下标,返回数组的值而已,没啥好分析的。

    到此,栈就分析差不多了。我们可以发现,栈的实现还是相对简单的。
    通过阅读源码,我们确实可以对集合的理解加深,并且对数组结构的运用有更深刻的认识。


    有疑问,扫我二维码添加微信,欢迎骚扰!
    坚持做一件事,一起学习。


  • 相关阅读:
    阿里早期Android加固代码的实现分析
    如何利用C++的time头文件获取系统时间
    Python编写基于socket的非阻塞多人聊天室程序(单线程&多线程)
    Dalvik模式下在Android so库文件.init段、.init_array段构造函数上下断点
    手动绕过百度加固Debug.isDebuggerConnected反调试的方法
    request使用代理
    requests爬取豆瓣热门电视剧
    scrapy-继承默认的user-agent 中间件
    scrapy-下载器中间件 随机切换user_agent
    scrapy 直接在编辑器运行
  • 原文地址:https://www.cnblogs.com/lizb0907/p/10561011.html
Copyright © 2011-2022 走看看