Java Stack(堆栈)语法知识点详解
一、概述
栈(Stack)是一种后进先出(Last In First Out, LIFO)或先进后出(First In Last Out, FILO)的数据结构,它只允许在一端(栈顶)进行插入(入栈)和删除(出栈)操作。
二、语法知识点
-
声明栈
- 使用
Stack
类(java.util
包下)来声明一个栈。 Stack<E>
表示栈中元素的类型为E
。
Stack<Integer> stack = new Stack<Integer>(); // 声明一个Integer类型的栈
- 使用
-
栈的基本操作
- 入栈(Push):使用
push(E item)
方法将元素压入栈顶。 - 出栈(Pop):使用
pop()
方法移除栈顶元素,并返回该元素。 - 查看栈顶元素(Peek):使用
peek()
方法查看栈顶元素但不移除它。 - 检查栈是否为空(Empty):使用
empty()
方法检查栈是否为空。 - 查找元素位置(Search):使用
search(Object o)
方法返回栈中指定元素的位置(从1开始)。
- 入栈(Push):使用
-
栈的实现
Stack
类是Vector
类的一个子类,因此栈的底层实现是基于数组的。- 栈的操作(如入栈和出栈)会受到数组容量的限制,当数组满时,需要进行动态扩展。
三、代码示例及注释
import java.util.Stack;public class StackDemo {public static void main(String[] args) {// 声明一个Integer类型的栈Stack<Integer> stack = new Stack<Integer>();// 入栈操作stack.push(10); // 将10压入栈顶stack.push(20); // 将20压入栈顶stack.push(30); // 将30压入栈顶// 查看栈顶元素Integer topElement = stack.peek();System.out.println("栈顶元素: " + topElement); // 输出: 栈顶元素: 30// 出栈操作Integer poppedElement = stack.pop();System.out.println("出栈元素: " + poppedElement); // 输出: 出栈元素: 30// 检查栈是否为空boolean isEmpty = stack.empty();System.out.println("栈是否为空: " + isEmpty); // 输出: 栈是否为空: false// 查找元素位置int index = stack.search(20);System.out.println("元素20的位置: " + index); // 输出: 元素20的位置: 2// 遍历栈System.out.println("栈中的元素:");for (Integer element : stack) {System.out.println(element);}// 输出:// 栈中的元素:// 10// 20}
}
四、注意事项
-
溢出和下溢:
- 溢出(Overflow):当栈已满时,再执行入栈操作会导致溢出异常。
- 下溢(Underflow):当栈为空时,再执行出栈操作会导致下溢异常(
EmptyStackException
)。
-
线程安全:
Stack
类中的方法是同步的,因此它是线程安全的。但在多线程环境下,建议使用ConcurrentLinkedDeque
等并发集合类。
-
栈的应用:
- 栈常用于实现递归、函数调用、表达式求值等场景。
当然可以,以下是一些关于栈(Stack)的具体案例,涵盖了栈的基本操作及其应用场景:
一、栈的基本操作案例
-
创建栈
- 使用Java的集合类Stack来创建栈。
Stack<Integer> stack = new Stack<Integer>();
-
入栈(Push)
- 将元素添加到栈顶。
stack.push(1); stack.push(2); stack.push(3);
-
出栈(Pop)
- 从栈顶移除元素,并返回被移除的元素。
int element = stack.pop(); // 返回并移除栈顶元素 System.out.println(element); // 输出: 3
-
访问栈顶元素(Peek)
- 获取栈顶元素,但不对栈进行修改。
int element = stack.peek(); // 返回栈顶元素但不移除 System.out.println(element); // 输出: 3(假设栈顶元素为3)
-
判断栈是否为空
- 使用isEmpty()方法判断栈是否为空。
boolean empty = stack.isEmpty(); System.out.println(empty); // 输出: false(假设栈不为空)
二、栈的应用场景案例
-
方法调用和返回
- 在方法调用时,会使用栈的特性将方法调用的信息存储在栈帧中,然后依次执行,直到返回。这是栈在计算机程序执行中的一个重要应用。
-
表达式求值
- 计算机编译器和解释器在求解表达式时会使用栈来保存操作数和运算符。例如,在计算表达式“3 + 5 * 2”时,可以使用栈来保存操作数3、5、2和运算符+、*,并按照运算的优先级进行计算。
-
撤销操作
- 编辑器和设计软件通常使用栈来实现撤销和重做的功能。当用户进行某些操作时,可以将这些操作的信息压入栈中。当用户需要撤销操作时,可以从栈中弹出最近的操作并进行撤销。
三、自定义栈类案例
除了使用Java的集合类Stack外,还可以自定义一个栈类来实现栈的操作。以下是一个简单的自定义栈类的示例:
public class CustomStack {private int[] elements;private int size;private static final int DEFAULT_CAPACITY = 10;public CustomStack() {elements = new int[DEFAULT_CAPACITY];size = 0;}public void push(int element) {ensureCapacity();elements[size++] = element;}public int pop() {if (size == 0) {throw new EmptyStackException();}return elements[--size];}public int peek() {if (size == 0) {throw new EmptyStackException();}return elements[size - 1];}public boolean isEmpty() {return size == 0;}private void ensureCapacity() {if (size == elements.length) {int[] newElements = new int[elements.length * 2];System.arraycopy(elements, 0, newElements, 0, elements.length);elements = newElements;}}public int size() {return size;}
}
使用自定义栈类进行栈的操作:
public class CustomStackExample {public static void main(String[] args) {CustomStack stack = new CustomStack();stack.push(1);stack.push(2);stack.push(3);int topElement = stack.peek();System.out.println("栈顶元素是: " + topElement); // 输出: 栈顶元素是: 3stack.pop();System.out.println("弹出栈顶元素后,栈顶元素是: " + stack.peek()); // 输出: 弹出栈顶元素后,栈顶元素是: 2}
}
以上案例展示了栈的基本操作以及其在实际编程中的应用场景。通过理解栈的原理和基本操作,可以更好地利用栈这种数据结构来提高程序的效率和可读性。