Stack
Stack — класс из пакета java.util, реализующий классический стек LIFO («последним пришёл — первым вышел»). Унаследован от Vector, поэтому помимо стековых методов поддерживает все методы списка.
В современном Java-коде вместо Stack чаще используют Deque<E> (например, ArrayDeque) — он не синхронизирован и быстрее. Тем не менее Stack остаётся в стандартной библиотеке и часто встречается в учебных задачах и в существующем коде.
Зачем нужен
Хранение истории действий с поддержкой «отмены» (undo).
Обход деревьев и графов в глубину (DFS).
Разбор скобок, инфиксных и постфиксных выражений.
Любая логика, где важна именно LIFO-семантика.
Конструкторы
Stack()— пустой стек.
Популярные методы
push(E item)— положить элемент на вершину.pop()— снять и вернуть верхний элемент; бросаетEmptyStackExceptionесли стек пуст.peek()— посмотреть верхний элемент, не снимая; то же исключение, если пусто.empty()—trueесли стек пуст.search(Object o)— позиция элемента от вершины (1 = на вершине),-1если нет.size()— текущий размер.
Пример 1. Базовые операции
import java.util.Stack;
public class Basics {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println("Вершина: " + stack.peek());
System.out.println("Снимаем: " + stack.pop());
System.out.println("Стек: " + stack);
}
}
Вывод:
Вершина: C
Снимаем: C
Стек: [A, B]
Пример 2. Опустошение стека
import java.util.Stack;
public class DrainStack {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
for (int i = 1; i <= 4; i++) stack.push(i);
while (!stack.empty()) {
System.out.print(stack.pop() + " ");
}
System.out.println();
}
}
Вывод:
4 3 2 1
Пример 3. Реверс строки
import java.util.Stack;
public class ReverseString {
public static void main(String[] args) {
String input = "AlashEd";
Stack<Character> stack = new Stack<>();
for (char c : input.toCharArray()) stack.push(c);
StringBuilder sb = new StringBuilder();
while (!stack.empty()) sb.append(stack.pop());
System.out.println(sb);
}
}
Вывод:
dEhsalA
Пример 4. Проверка сбалансированности скобок
import java.util.Stack;
public class Brackets {
public static boolean isBalanced(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(' || c == '[' || c == '{') stack.push(c);
else if (c == ')' || c == ']' || c == '}') {
if (stack.empty()) return false;
char open = stack.pop();
if (open == '(' && c != ')') return false;
if (open == '[' && c != ']') return false;
if (open == '{' && c != '}') return false;
}
}
return stack.empty();
}
public static void main(String[] args) {
System.out.println(isBalanced("(a+b)*[c-d]"));
System.out.println(isBalanced("(a+b]"));
System.out.println(isBalanced("{[()]}"));
}
}
Вывод:
true
false
true
Пример 5. Поиск позиции элемента
import java.util.Stack;
public class SearchPos {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.push("Arduino");
stack.push("ESP32");
stack.push("RPi");
System.out.println("RPi: " + stack.search("RPi"));
System.out.println("ESP32: " + stack.search("ESP32"));
System.out.println("Arduino: " + stack.search("Arduino"));
System.out.println("Linux: " + stack.search("Linux"));
}
}
Вывод:
RPi: 1
ESP32: 2
Arduino: 3
Linux: -1
Пример 6. Undo-история
import java.util.Stack;
public class UndoHistory {
public static void main(String[] args) {
Stack<String> history = new Stack<>();
history.push("draw_line");
history.push("draw_circle");
history.push("fill_red");
System.out.println("Undo: " + history.pop());
System.out.println("Undo: " + history.pop());
System.out.println("Осталось: " + history);
}
}
Вывод:
Undo: fill_red
Undo: draw_circle
Осталось: [draw_line]
Пример 7. EmptyStackException
import java.util.Stack;
public class EmptyDemo {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
try {
stack.pop();
} catch (Exception e) {
System.out.println("Поймали: " + e.getClass().getSimpleName());
}
}
}
Вывод:
Поймали: EmptyStackException
Пример 8. Постфиксный калькулятор
import java.util.Stack;
public class Postfix {
public static int compute(String expr) {
Stack<Integer> st = new Stack<>();
for (String tok : expr.split(" ")) {
switch (tok) {
case "+": st.push(st.pop() + st.pop()); break;
case "*": st.push(st.pop() * st.pop()); break;
case "-": { int b = st.pop(); int a = st.pop(); st.push(a - b); break; }
default: st.push(Integer.parseInt(tok));
}
}
return st.pop();
}
public static void main(String[] args) {
System.out.println(compute("3 4 + 2 *"));
System.out.println(compute("5 1 2 + 4 * + 3 -"));
}
}
Вывод:
14
14
См. также
Примечание
Описание основано на официальной документации Oracle Java SE 21 API (https://docs.oracle.com/en/java/javase/21/docs/api/). Материал распространяется на условиях Oracle Free Documentation License. Тексты статьи написаны редакцией AlashEd своими словами; примеры кода — авторские.