参照: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;
}

最新文章

  1. win7系统中如何使文件显示出扩展名
  2. Java内存浅析分类
  3. MySQL中优化常用的查询sql语
  4. 临床试验中PI、CI、SI、COI是指哪些人?
  5. 【linux】 静态库编译
  6. HDU 1564 (博弈) Play a game
  7. PHP获取上个月、下个月、本月的日期(strtotime(),date())
  8. hibernate uniqueResult方法
  9. ural 1572 Yekaterinozavodsk Great Well
  10. [转]详解AppDelegate/UIApplication
  11. Python之路第九天,高级(1)-网络编程
  12. Js把URL中的参数解析为一个对象
  13. pl/sql 中F8执行单行sql
  14. bzoj4871 [Heoi2017]摧毁“树状图”
  15. 学习记录(一)之h5_canvas
  16. Python3 读写文件
  17. tensorflow:验证码的识别(中)
  18. BZOJ.2199.[USACO2011 Jan]奶牛议会(2-SAT)
  19. linux之shell终端使用操作快捷键
  20. nexage video asset tag

热门文章

  1. (转载)Newtonsoft.Json使用总结
  2. 给广大码农分享福利:一个业界良心的github仓库,中文计算机资料
  3. 复杂UI的组织-创建者模式-uitableview思想
  4. unbuntu&amp;vim&amp;Kali的各种小知识
  5. php的字符转换 &amp; php登入注册界面设计以及源码 &amp; 分离公共部分
  6. c#—OpenFileDialog
  7. Codeforces 517 #A
  8. PAT 乙级 1086
  9. 【点分治】luoguP2664 树上游戏
  10. mysqlfailover高可用与proxysql读写分离配置