Stack类是Vector类的子类,由它创建的容器又叫栈容器。在之前我们分析java程序中的内存变化的时候,我们就曾经介绍过栈内存,栈内存的存储特点是后进先出,先进栈的方法后退出。与占内存的存储类似,Stack容器实现的就是一个标准的后进先出的存储模式。
那么如何理解这个后进先出的存储模式呢?这里我们用一个非常简单的例子来进行说明。在我们打羽毛球或者去商店购买羽毛球的时候应该都能发现羽毛球是从一个圆筒状的容器中取出的,这样我们定义四个羽毛球,分别标记为1号、2号、3号以及4号。在存储这些羽毛球时,我们按照1、2、3、4的顺序将其放到圆筒状的容器中,这时1号羽毛球是第一个被放入容器的,而4号羽毛球是最后一个被放入容器的。当我们要取出这个圆筒中的羽毛球时最先被拿到的是4号羽毛球,最后拿到的是1号羽毛球,这就是一个后进先出的例子。
在java中,Stack容器作为Vector容器类的子类,它提供了五个额外的方法来扩展了Vector容器类。着五个方法分别是:empty、peek、pop、push以及serch。
boolean empty() :测试这个栈容器中是否含有元素,没有元素时发返回boolean类型的值true,否则返回boolean类型的值false;
E peek() :查询栈顶的元素,并返回栈顶元素的值,但不会删除栈顶元素;
E pop() :查询栈顶元素,并将栈顶元素的值返回,但会将栈顶的元素删除;
E push(E item) :将指定的元素添加到栈容器的顶部,并返回该元素的值;
int serch(Object o) :查询指定元素在栈容器中的位置,并且返回该位置,如果不存在该元素则返回值-1。
值得注意的是,虽然栈容器Stack是Vector的子类,但是它的计数方式却和数组的计数方式不相同。栈容器的计数是从1开始的,并且它遵循的是从后往前的顺序,比如在下面的演示代码中,我们创建了一个栈容器stack1,在这个容器中依次添加了元素a b c ,当我们通过search方法查询此容器中元素的位置时能发现组后添加进容器的元素c的位置为1,而最先添加进容器的元素a的位置的3。这一点与我们之前学习的容器类均有区别,不要陷入先入为主的思维陷阱。
此外还要特别注意的是方法pop和方法peek的使用,这两个方法都能获取栈顶元素,也就是最后加入容器的元素,但是pop方法在获取栈顶元素的同时会删除这个栈顶元素,相当于将这个栈顶元素从容器中取出了。这里我们可以这样区别这两个方法,如果我用peek方法去获取一个栈顶元素,获取完这个栈顶元素之后我还想在获取同一个栈容器中的栈顶元素,这时我们在调用peek方法,会法发现我们两次获取的栈顶元素是一样的,也就是说栈顶元素没有改变。但是如果我们用pop方法来获取栈顶元素时结果是不一样的,比如在下面的演示代码中,我们用pop方法第一次获取了栈顶元素,这时栈容器为stack: a b c,所以栈顶元素应该是c,而当我下一次获取栈顶元素时栈容器变为了stack: a b ,所以这时的栈顶元素应为b,可以法现栈顶元素发生了改变。
package com.container.demo;
import java.util.Stack;
public class StackTest {
public static void main(String[] args) {
//实例化栈容器
Stack<String> stack = new Stack<>();
//将元素添加到栈容器种
stack.push("a");
stack.push("b");
stack.push("c");
//查看栈顶元素,并不会删除该元素
System.out.println("用peek方法查看栈顶元素,其结果为:");
String stack1 = stack.peek();
System.out.println(stack1);
//查看指定元素在栈容器中的位置。在栈容器中,元素计数从1开始,并且顺序由后往前,从栈顶开始
System.out.println("查看指定元素在栈容器中对应的位置:");
int ind1 = stack.search("a");
int ind2 = stack.search("b");
int ind3 = stack.search("c");
System.out.println("a的位置为:"+ind1);
System.out.println("b的位置为:"+ind2);
System.out.println("c的位置为:"+ind3);
//获取栈顶元素,并将带元素从栈容器中删除
System.out.println("用pop方法获取栈顶元素:");
String s1 = stack.pop();
String s2 = stack.pop();
String s3 = stack.pop();
System.out.println("第一次调用pop方法的结果为:"+s1);
System.out.println("第二次调用pop方法的结果为:"+s2);
System.out.println("第三次调用pop方法的结果为:"+s3);
//查看该栈容器是否为空
System.out.println("查看容器是否为空:");
boolean bo = stack.empty();
System.out.println("容器是否为空:"+bo);
}