一:类的继承关系
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);
}

分析:这个方法就是根据下标,返回数组的值而已,没啥好分析的。


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


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


jdk1.8-stack 栈源码分析的更多相关文章

  1. Stack的源码分析和应用实例

    1.Stack介绍 Stack是栈.它的特性是:先进后出(FILO:First In Last Out). java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实 ...

  2. Java集合基于JDK1.8的LinkedList源码分析

    上篇我们分析了ArrayList的底层实现,知道了ArrayList底层是基于数组实现的,因此具有查找修改快而插入删除慢的特点.本篇介绍的LinkedList是List接口的另一种实现,它的底层是基于 ...

  3. Java -- 基于JDK1.8的LinkedList源码分析

    1,上周末我们一起分析了ArrayList的源码并进行了一些总结,因为最近在看Collection这一块的东西,下面的图也是大致的总结了Collection里面重要的接口和类,如果没有意外的话后面基本 ...

  4. JDK1.7之 HashMap 源码分析

    转载请注明出处:http://blog.csdn.net/crazy1235/article/details/75451812 类继承关系 构造函数 Entry put put putForNullK ...

  5. Java -- 基于JDK1.8的ThreadLocal源码分析

    1,最近在做一个需求的时候需要对外部暴露一个值得应用  ,一般来说直接写个单例,将这个成员变量的值暴露出去就ok了,但是当时突然灵机一动(现在回想是个多余的想法),想到handle源码里面有使用过Th ...

  6. Java集合基于JDK1.8的ArrayList源码分析

    本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集 ...

  7. 基于jdk1.8的ArrayList源码分析

    前言ArrayList作为一个常用的集合类,这次我们简单的根据源码来看看AarryList是如何使用的. ArrayList拥有的成员变量 public class ArrayList<E> ...

  8. Java -- 基于JDK1.8的ArrayList源码分析

    1,前言 很久没有写博客了,很想念大家,18年都快过完了,才开始写第一篇,争取后面每周写点,权当是记录,因为最近在看JDK的Collection,而且ArrayList源码这一块也经常被面试官问道,所 ...

  9. Stack&Vector源码分析 jdk1.6

    参照:http://www.cnblogs.com/tstd/p/5104099.html Stack(Fitst In Last Out) 1.定义 public class Stack<E& ...

随机推荐

  1. Vue-指令补充、过滤器、计数器属性、监听属性

    vue实例成员: el | template |data | methods watch 监听事件| computed 计数属性使用 | filters过滤器 | props 父传子 componen ...

  2. 快速取出选中checkbox的值

    原料:jquery 直接上代码 html代码 <html> <head> <title>$Title$</title> </head> &l ...

  3. Python之PyLint自动检查代码

    PyLint的下载地址:https://pypi.python.org/pypi/pylint PyLint的官网:http://www.pylint.org/ 从源码发行版安装,解压文件包并且运行 ...

  4. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  5. TCP数据段格式+UDP数据段格式详解

    TCP 报文格式 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TCP 报文段的报头有 10 个必需的字段和 ...

  6. hive2.3.4安装

    一.安装Hadoop Hive运行在Hadoop环境之上,因此需要hadoop环境,本次在安装在hadoop完全分布式模式的namennode节点上 请参考:hadoop搭建 二.安装Hive 下载 ...

  7. Spring——顾问封装通知

    通知(advice)是Spring中的一种比较简单的切面,只能将切面织入到目标类的所有方法中,而无法对指定方法进行增强 顾问(advisor)是Spring提供的另外一种切面,可以织入到指定的方法中  ...

  8. finally应用

    finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下. 之前在写爬虫的时候数据 ...

  9. git上传项目已经删除文件,但是Jenkins中没有删除

    jenkins 缓存造成的,需要清理工作空间

  10. Windows10 修改键位映射

    https://blog.csdn.net/lhdalhd1996/article/details/90741092 1.为什么要修改键位我的笔记本键盘上下键是这样的: 很想捶死产品经理,你是从来不用 ...