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--------------------
Java源码阅读Stack的更多相关文章
- Java源码阅读的真实体会(一种学习思路)
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈 ...
- Java源码阅读的真实体会(一种学习思路)【转】
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+ ...
- java1.7集合源码阅读: Stack
Stack类也是List接口的一种实现,也是一个有着非常长历史的实现,从jdk1.0开始就有了这个实现. Stack是一种基于后进先出队列的实现(last-in-first-out (LIFO)),实 ...
- 如何阅读Java源码 阅读java的真实体会
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比 ...
- [收藏] Java源码阅读的真实体会
收藏自http://www.iteye.com/topic/1113732 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我 ...
- java源码阅读Hashtable
1类签名与注释 public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, C ...
- java源码解析——Stack类
在java中,Stack类继承了Vector类.Vector类和我们经常使用的ArrayList是类似的,底层也是使用了数组来实现,只不过Vector是线程安全的.因此可以知道Stack也是线程安全的 ...
- Java源码阅读顺序
阅读顺序参考链接:https://blog.csdn.net/qq_21033663/article/details/79571506 阅读源码:JDK 8 计划阅读的package: 1.java. ...
- java源码阅读LinkedBlockingQueue
1类签名与简介 public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements Blocking ...
随机推荐
- 【CF edu 27 G. Shortest Path Problem?】
time limit per test 3 seconds memory limit per test 512 megabytes input standard input output standa ...
- 文件搜索工具everything
Everything是voidtools开发的一款文件搜索工具,官网描述为“基于名称实时定位文件和目录(Locate files and folders by name instantly) (“Ev ...
- linux精彩收集
----------------------------网络无关篇-------------------------- 0001 修改主机名(bjchenxu) vi /etc/sysconfig/n ...
- ef unitofwork 主从表更新
readonly UnitOfWork _u = new UnitOfWork(); public M Get(int id) { return _u.T_MtnContractRepository( ...
- UVALIVE 3031 Cable TV Network
题意:求点联通度 首先看了别人的题解还是不晓得只枚举汇点的原因觉得行不通 关于求点联通度的建图方法 转自http://hi.baidu.com/lerroy312/item/5a5f36f2f5bba ...
- mogadm修改硬盘状态
#查看主机序列mogadm host list #查看空间快满的分区 df -h#检查硬盘序列和状态ls -l /data/mogile_data/ #查看mogadm目录下软链接的目录对应的分区 # ...
- hadoop使用supervisord
#安装 wget https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b ...
- springBoot Ribbon Hystrix Dashboard
1.引入依赖 <!-- 引入关于 hystrix Dashboard的依赖 --> <dependency> <groupId>org.springframewor ...
- AC日记——[国家集训队2011]旅游(宋方睿) cogs 1867
[国家集训队2011]旅游(宋方睿) 思路: 树链剖分,边权转点权: 线段树维护三个东西,sum,max,min: 当一个区间变成相反数时,sum=-sum,max=-min,min=-max: 来, ...
- CF978B File Name【数组操作/序列判断连续出现>=3次的‘x’个数】
CF978B File Name [分析]:设置计数器cnt,计数x的个数:遇到非x,若cnt>=3的话累加多出的个数,计数器清零:若最后cnt>=3说明没遇到非x无法清零,那后部分就都是 ...