点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~


今天心情不错,再来一篇 Stack !

数据结构中的 栈

数据结构中,栈是一种线性数据结构,遵从 LIFO(后进先出)的操作顺序,所有操作都是在顶部进行

有点像羽毛球筒:

栈通常有三种操作:

  • push 入栈
  • pop 栈顶元素出栈,并返回
  • peek 获取栈顶元素,并不删除

我们自定义一个 栈 时只要实现上述三个主要操作即可,本文中将使用 Java 中的 LinkedList 实现一个栈。

栈的使用场景:

栈最主要的意义就在于:入栈和出栈的对称性。

在 Android 开发中,我们经常需要开启、回退一个 Activity,其实这里就有栈的应用,每次开启Activity,如果不是特殊的启动模式,就会在栈顶加入一个 Activity,点击返回后,之前的 Activity 出栈 。

其他场景比如递归(斐波那契数列,汉诺塔)。

Java 集合框架中的栈 Stack

Java 集合框架中的 Stack 继承自 Vector:

  • 由于 Vector 有 4 个构造函数,加上 Stack 本身的一种,也就是说有 5 中创建 Stack 的方法
  • 跟 Vector 一样,它是 数组实现的栈

Stack 的方法

Stack 中新建的方法比较少:

1.构造函数

//构建一个空栈
public Stack() {
}

2.入栈

//调用的 Vector.addElement()
public E push(E item) {addElement(item);return item;
}

Vector 的 addElement() 方法,就是在数组尾部添加元素:

public synchronized void addElement(E obj) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = obj;
}

3.获取顶端元素,但不删除

public synchronized E peek() {//调用 Vector.size() 返回元素个数int     len = size();if (len == 0)throw new EmptyStackException();//调用 Vector.elementAt 得到栈顶元素return elementAt(len - 1);
}

Vector.elementAt(int):

public synchronized E elementAt(int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);}return elementData(index);
}

Vector.elementData(int):

E elementData(int index) {return (E) elementData[index];
}

4.出栈

public synchronized E pop() {E       obj;int     len = size();//调用 peek() 获取顶端元素,一会儿返回obj = peek();//调用 Vector.removeElementAt 删除顶端元素removeElementAt(len - 1);return obj;
}

Vector.removeElementAt(int):

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; /* to let gc do its work */
}

5.查找元素是否在栈中

public synchronized int search(Object o) {int i = lastIndexOf(o);//返回的是栈顶到该元素出现的位置的距离if (i >= 0) {return size() - i;}return -1;
}

6.是否为空

public boolean empty() {return size() == 0;
}

Vector.size():

public synchronized int size() {return elementCount;
}

总结

Java 集合框架中的 Stack 具有以下特点:

  • 继承自 Vector
  • 有 5 种创建 Stack 的方法
  • 采用数组实现
  • 除了 push(),剩下的方法都是同步的

用链表实现一个栈?

由于 Stack 是用数组实现的,我们用链表实现一下吧,这里就选择 LinkedList 来实现:

/*** description:LinkedList 模拟 Stack* <br/>* author: shixinzhang* <br/>* data: 10/23/2016*/
public class LinkedListStack extends LinkedList{public LinkedListStack(){super();}@Overridepublic void push(Object o) {super.push(o);}@Overridepublic Object pop() {return super.pop();}@Overridepublic Object peek() {return super.peek();}@Overridepublic boolean isEmpty() {return super.isEmpty();}public int search(Object o){return indexOf(o);}
}

调用:

@Test
public void testPush() throws Exception {LinkedListStack stack = new LinkedListStack();System.out.println("栈是否为空: " + stack.isEmpty());stack.push("shixin");stack.push("好帅");stack.push("技巧一流");stack.push("haha");System.out.println("栈中元素: " + stack);System.out.println("获取顶端元素 peek :" + stack.peek());System.out.println("顶端元素出栈 pop :" + stack.pop());System.out.println("出栈后栈内元素:" + stack);System.out.println("search(好帅) 的位置:" + stack.search("好帅"));
}
}

结果:

可以看到,我其实都没做什么哈哈,都是 LinkedList 内部提供的方法,操作的都是在链表头部的元素,而不是尾部。

其实 LinkedList 这个栈的特性也是继承自 双端队列 Deque,官方也推荐在使用栈时优先使用 Deque,而不是 Stack,有兴趣的可以去了解下。

Thanks

https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html

http://www.cnblogs.com/kaituorensheng/archive/2013/03/02/2939690.html

http://www.nowamagic.net/librarys/veda/detail/2298

Java 集合深入理解(13):Stack 栈相关推荐

  1. java方法的理解、调用栈与异常处理

    java方法的理解.调用栈与异常处理 参考文章: (1)java方法的理解.调用栈与异常处理 (2)https://www.cnblogs.com/yangxiansen/p/7860058.html ...

  2. Java 集合深入理解 (十一) :HashMap之实现原理及hash碰撞

    文章目录 前言 哈希表原理 实现示例 HashMap实现原理 全篇注释分析 实现注意事项 默认属性分析 属性分析 构造方法分析 重要的put方法 总结 前言 哈希表(hashMap)又叫散列表 是一种 ...

  3. Java 集合深入理解(12):古老的 Vector

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天刮台风,躲屋里看看 Vector ! 都说 Vector 是线程安全的 ArrayList,今天来根据源码看看是不是这 ...

  4. Java 集合深入理解(16):HashMap 主要特点和关键方法源码解读

    >点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 前面我们介绍了 哈希相关概念:哈希 哈希函数 冲突解决 哈希表,这篇文章我们来根据 JDK 1.8 源码,深入了解 ...

  5. Java 集合深入理解(9):Queue 队列

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情不太好,来学一下 List 吧! 什么是队列 队列是数据结构中比较重要的一种类型,它支持 FIFO,尾部添加.头部 ...

  6. Java 集合深入理解(10):Deque 双端队列

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...

  7. Java 集合深入理解(11):LinkedList

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天心情鱼肚白,来学学 LinkedList 吧! 日常开发中,保存一组数据使用的最多的就是 ArrayList, 其次就 ...

  8. Java 集合深入理解(15):AbstractMap

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 今天来了解下 AbstractMap. 什么是 AbstractMap AbstractMap 是 Map 接口的的实现类 ...

  9. Java 集合深入理解(17):HashMap 在 JDK 1.8 后新增的红黑树结构

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 上篇文章我们介绍了 HashMap 的主要特点和关键方法源码解读,这篇文章我们介绍 HashMap 在 JDK1.8 新增 ...

最新文章

  1. mysql数据压缩加密_MySQL 加密/压缩函数
  2. python输入姓名输出欢迎_python 3 基础之输入输出
  3. 计算机兴趣班记录,计算机兴趣班活动记录.doc
  4. 交叉表组件(改造 适用多个子标题)
  5. idea的terminal是一个终端命令行,你知道吗?
  6. post工具_GitHub CLI 命令行工具使用
  7. 波形捕捉:(8)使用“捕捉缓冲区”
  8. 如何将知识图谱引入推荐系统?
  9. android 布局变化动画效果,使用LayoutTransition实现布局变化时的动画
  10. hibernate 映射表_Hibernate多对多映射-连接表
  11. 55. mysqli 扩展库(2)
  12. 图像边缘检测的新方向——量子算法
  13. 百度搜索算法全解析SEO课程笔记
  14. shp文件格式说明(二)
  15. 北京市工作居住证的申请与办理
  16. Oracle数据库-第三章:单值函数
  17. 百度细雨算法2.0正式上线
  18. 2021届秋招—中兴面试(软件开发C++方向)
  19. ae cs6安装2%报错
  20. Ron Patton软件测试习题:黑盒测试、白盒测试

热门文章

  1. [poj 1737] Connected Graph {高精度+动态规划}
  2. swust1737: 太空飞行计划问题
  3. 【数字图像处理】-- 弄懂等距变换(刚性变换)、相似变换、仿射变换、透视变换(投影变换)
  4. 其实,“把梳子卖给和尚”不是营销
  5. win10 Snipaste 截图软件
  6. 对千变万化数据的处理 12work
  7. 关于朴素贝叶斯分类算法(Naive Bayesian classification)
  8. 一个极简、高效的秒杀系统-战略设计篇
  9. matlab仿真加入反冲模块,saturation模块作用
  10. android 2048的简单实现