一、Stack 概述
1、Stack 是栈结构,它继承与 Vector。它的特性是:先进后出(FILO,First In Last Out)或 后进先出(LIFO,Last In First Out);
2、Stack是Vector的子类,比Vector多了几个方法,它的后进先出的特征,就是通过调用这几个方法实现的。
3、
4、
5、
二、Stack 结构
1、Stack 类声明
public class Stack<E> extends Vector<E>
可以发现 Stack 是 Vector 的子类。
2、Stack 类继承结构
3、
4、
三、Stack 创建
1、构造器
源码:
1 public Stack() {}
Stack 只提供了一个无参的构造器,但是这里会调用父类的构造器:
1 public Vector() {
2 this(10);
3 }
可以发现,在这里创建了一个长度为10的数组。
2、添加元素
通过 Stack 的 push() 方法,可以向栈中添加元素,本质还是调用父类 Vector 的 addElement() 方法:
1 public synchronized void addElement(E obj) {
2 modCount++;
3 ensureCapacityHelper(elementCount + 1);
4 elementData[elementCount++] = obj;
5 }
可以发现,如果需要进行扩容的话也是调用 vector 中的扩容方式来扩容的,即容量扩容为原来的2倍。
3、
四、Stack 方法
1、方法列表
2、push(E) 方法
把元素压入栈顶,等价于add(item),这里为了更形象化,单独设计了一个push。
源码:
1 public E push(E item) {
2 addElement(item);
3
4 return item;
5 }
6 // 调用 Vector 的 addElement() 方法
7 public synchronized void addElement(E obj) {
8 modCount++;
9 ensureCapacityHelper(elementCount + 1);
10 elementData[elementCount++] = obj;
11 }
在JDK9 中:
然后调用 Vector 中的 add 方法:
3、pop() 方法:弹出栈顶元素
源码:
1 public synchronized E pop() {
2 E obj;
3 int len = size();
4
5 obj = peek();
6 removeElementAt(len - 1);
7
8 return obj;
9 }
10
11 // 调用 Vector 的removeElementAt()方法
12 public synchronized void removeElementAt(int index) {
13 modCount++;
14 if (index >= elementCount) {
15 throw new ArrayIndexOutOfBoundsException(index + " >= " +
16 elementCount);
17 }
18 else if (index < 0) {
19 throw new ArrayIndexOutOfBoundsException(index);
20 }
21 int j = elementCount - index - 1;
22 if (j > 0) {
23 System.arraycopy(elementData, index + 1, elementData, index, j);
24 }
25 elementCount--;
26 elementData[elementCount] = null; /* to let gc do its work */
27 }
4、peek() 方法:获取栈顶元素,不移除
源码:
1 public synchronized E peek() {
2 int len = size();
3
4 if (len == 0)
5 throw new EmptyStackException();
6 return elementAt(len - 1);
7 }
8
9 public synchronized E elementAt(int index) {
10 if (index >= elementCount) {
11 throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
12 }
13
14 return elementData(index);
15 }
16
17 E elementData(int index) {
18 return (E) elementData[index];
19 }
5、empty() 方法
源码:
1 public boolean empty() {
2 return size() == 0;
3 }
6、search(Object) 方法:返回的是从栈顶开始计算索引位置的
源码:
1 public synchronized int search(Object o) {
2 int i = lastIndexOf(o);
3
4 if (i >= 0) {
5 return size() - i;
6 }
7 return -1;
8 }
9
10 public synchronized int lastIndexOf(Object o) {
11 return lastIndexOf(o, elementCount-1);
12 }
13
14 public synchronized int lastIndexOf(Object o, int index) {
15 if (index >= elementCount)
16 throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
17
18 if (o == null) {
19 for (int i = index; i >= 0; i--)
20 if (elementData[i]==null)
21 return i;
22 } else {
23 for (int i = index; i >= 0; i--)
24 if (o.equals(elementData[i]))
25 return i;
26 }
27 return -1;
28 }
五、案例
1、数组模拟栈一
1 class ArrayStack {
2 private int[] data; //存储数据
3 private int size; //元素的个数
4
5 //默认容量
6 private static final int DEFAULT_CAPACITY = 10;
7
8 ArrayStack() {
9 data = new int[DEFAULT_CAPACITY];
10 }
11
12 ArrayStack(int capacity) {
13 data = new int[capacity];
14 }
15
16 //把item压入堆栈顶部
17 public void push(int ele) {
18 //判断是否需要扩容
19 if (size > data.length) {
20 data = Arrays.copyOf(data, data.length * 2);
21 }
22 data[size++] = ele;
23 }
24
25 //查看堆栈顶部的对象,但不从堆栈中移除它
26 public int peek() {
27 if (size == 0) {
28 throw new EmptyStackException();
29 }
30 return data[size-1]; //获取栈顶元素
31 }
32
33 //移除堆栈顶部的对象,并作为此函数的值返回该对象
34 public int pop() {
35 int o = this.peek(); //获取栈顶元素
36 size--; //减少元素个数
37 return o;
38 }
39
40 //返回对象在栈中的位置,以 1 为基数,从栈顶开始计算
41 public int search(int ele) {
42 //顺着放倒着拿(FILO/LIFO)
43 for (int i = size - 1; i >=0; i--)
44 {
45 if (ele == data[i]) {
46 return size - i;
47 }
48 }
49 return -1; //返回栈中不存在该元素
50 }
51
52 public int size() {
53 return size;
54 }
55
56 //测试堆栈是否为空
57 public boolean empty() {
58 return size == 0;
59 }
60 }
2、数组模拟栈二
1 /**
2 * 定义一个ArrayStack 表示栈
3 */
4 public class MyArrayStack {
5 private int maxSize; // 栈的大小
6 private int[] stack; // 数组,数组模拟栈,数据就在该数组中
7 private int top = -1; // top 表示栈顶,初始化为 -1
8
9 // 构造器
10 public MyArrayStack(int maxSize) {
11 this.maxSize = maxSize;
12 stack = new int[this.maxSize];
13 }
14
15 // 判断栈满
16 public boolean isFull() {
17 return top == maxSize - 1;
18 }
19
20 // 判断栈空
21 public boolean isEmpty() {
22 return top == -1;
23 }
24
25 // 入栈 - push
26 public void push(int value) {
27 // 先判断栈是否满
28 if (isFull()) {
29 System.out.println("栈满");
30 return;
31 }
32 top++;
33 stack[top] = value;
34 }
35
36 // 出栈 - pop,将栈顶的数据返回
37 public int pop() {
38 // 先判断栈是否空
39 if (isEmpty()) {
40 // 抛出异常来处理
41 throw new RuntimeException("栈空,没有数据··");
42 }
43 int value = stack[top];
44 top--;
45 return value;
46 }
47
48 // 显示栈的情况[遍历栈],从栈顶往下显示数据
49 public void list() {
50 if (isEmpty()) {
51 System.out.println("栈空,没有数据~~");
52 return;
53 }
54
55 for (int i = top; i >= 0; i--) {
56 System.out.printf("stack[%d]=%d\n", i, stack[i]);
57 }
58 }
59 }