Класс Stack в Java — использование и примеры

Класс Stack расширяет класс Vector и позволяет создавать новые элементы, просматривать верхний элемент, обновлять элементы и удалять все элементы из стека. Стек обрабатывает данные по принципу «первым пришёл — последним ушёл» (FILO). Это означает, что добавление и удаление элементов выполняется только с вершины стека.
У структуры данных Stack есть пять основных методов, но класс Stack также унаследовал более 40 методов от Vector, которые доступны для произвольного доступа и операций над содержимым.
Создание стека в Java
Класс Stack имеет один конструктор, который создаёт пустой стек. Каждый Stack имеет параметр типа, который определяет, какие данные он будет хранить.
import java.util.Stack;
public class Main {
public static void main(String[] args) {
// создаём стек, в котором хранятся строки
Stack Customers = new Stack();
}
} Код выше создаёт структуру Stack с именем Customers, в которой хранятся значения типа String.
Заполнение стека
Один из пяти основных методов класса Stack — метод push(). Он принимает один элемент того же типа, что и стек, и помещает этот элемент на вершину стека.
// заполняем стек
Customers.push("Jane Doe");
Customers.push("John Doe");
Customers.push("Patrick Williams");
Customers.push("Paul Smith");
Customers.push("Erick Rowe");
Customers.push("Ella Jones");
Customers.push("Jessica Brown");Код выше наполняет стек Customers семью элементами. Каждый новый элемент помещается на вершину стека, поэтому верхним элементом является “Jessica Brown”. Подтвердить это можно с помощью метода peek(), который возвращает объект на вершине стека без его удаления.
// просмотреть объект на вершине стека
System.out.println(Customers.peek());Этот вывод в консоль покажет:
Jessica BrownПросмотр элементов стека
Стек ограничивает способы взаимодействия с данными: основной подход — работать с верхним элементом. Тем не менее, можно использовать методы, унаследованные от Vector, чтобы обращаться к произвольным элементам, например elementAt или removeElementAt.
Проще всего получить обзор содержимого стека, просто распечатав его: при передаче объекта Stack в System.out.println будет вызван его toString(), который возвращает представление в виде списка.
// вывести все элементы стека
System.out.println(Customers);Ожидаемый вывод:
[Jane Doe, John Doe, Patrick Williams, Paul Smith, Erick Rowe, Ella Jones, Jessica Brown]Поиск позиции элемента в стеке
Если вы знаете элемент в стеке, можно найти его индекс или позицию относительно вершины стека. Метод indexOf() принимает элемент и возвращает его индекс (нумерация с нуля).
// найти индекс элемента
System.out.println(Customers.indexOf("Jane Doe"));Выведет:
0Метод search() — один из основных методов класса Stack. Он возвращает позицию элемента относительно вершины стека, при этом элемент на вершине имеет позицию 1.
System.out.println(Customers.search("Jane Doe"));Выведет:
7Если передать в search() или indexOf() элемент, которого нет в стеке, метод вернёт -1.
System.out.println(Customers.search("Elsa Doe"));
System.out.println(Customers.indexOf("Elsa Doe"));Вывод:
-1
-1Обновление элементов в стеке
В стеке напрямую можно изменять только верхний элемент. Чтобы обновить элемент, находящийся глубже, нужно удалить (pop) все элементы выше него, изменить целевой элемент и затем вернуть (push) все ранее удалённые элементы обратно.
// обновление объекта
Customers.pop();
Customers.pop();
Customers.push("Ella James");
Customers.push("Jessica Brown");
System.out.println(Customers);Вывод:
[Jane Doe, John Doe, Patrick Williams, Paul Smith, Erick Rowe, Ella James, Jessica Brown]Процесс обновления включает в себя временное удаление верхних элементов, изменение целевого элемента и восстановление порядка. Для реального кода стоит оборачивать такие операции в методы с понятной семантикой и учитывать возможные исключительные ситуации (пустой стек).
Удаление одного элемента из стека
Удаление отдельного элемента обычно выполняется через pop(). Если удаляемый элемент не на вершине, предварительно нужно удалить элементы сверху.
// удалить верхний элемент
String removed = Customers.pop();
System.out.println("Удалён: " + removed);Если вы хотите удалить конкретный элемент, не только вершину, и сохранить остальные в порядке, обычно используют вспомогательный стек или список, чтобы временно хранить элементы.
Полная очистка стека
Чтобы удалить все элементы, можно использовать цикл с pop(), но эффективнее вызвать clear(), унаследованный от Vector. Он не возвращает значения, но очищает коллекцию.
// удалить все элементы стека
Customers.clear();
System.out.println(Customers.empty());Метод empty() возвращает true, если стек пуст, и false иначе. Пример вывода:
trueПрактические применения стека
Стек хорошо подходит для задач, где требуется обработка в обратном порядке или отслеживание состояния с возможностью отката. Примеры:
- Проверка палиндрома (слово читается одинаково в обе стороны).
- Преобразование десятичных чисел в двоичные с помощью деления и помещения остатков в стек.
- Реализация функционала отмены действий (undo) в приложениях.
- Игровые сценарии с возвратом к предыдущему ходу (например, отмена хода в шахматах).
Важно: стек ограничивает произвольный доступ к элементам, поэтому для задач, где нужны частые вставки/удаления в середине или быстрый случайный доступ, он не подходит.
Когда не использовать стек
- Если требуется быстрый произвольный доступ по индексу большого числа элементов.
- Если важна многопоточная безопасность: класс Stack синхронизирован изначально, но для современных многопоточных приложений чаще используют специализированные конкуррентные структуры или синхронизацию на уровне вызовов.
- Для больших объёмов данных, где нужно массовая фильтрация или агрегация — лучше подходят очереди, списки или специализированные коллекции.
Альтернативы и сравнение
- ArrayDeque и LinkedList как реализация стека с более современным API и без наследования от Vector.
- Deque интерфейс предоставляет push/pop/peek и более гибкие операции с обеих сторон.
- Для многопоточных сценариев: ConcurrentLinkedDeque или специализированные структуры из java.util.concurrent.
Краткая матрица совместимости:
- Stack — простота, унаследован от Vector, синхронизирован.
- ArrayDeque — производительность и гибкость, не синхронизирован.
- LinkedList — двусвязный список, поддерживает Deque интерфейс, удобен при частых вставках/удалениях.
Ментальные модели и эвристики
- Представляйте стек как стопку тарелок: класть и снимать можно только сверху.
- Если задача связана с откатом состояния — подумайте о стеке состояний.
- Для преобразований, которые требуют обратного порядка вывода, используйте стек.
Пример вспомогательной функции: обновление элемента глубже в стеке
Ниже шаблонный метод, который заменяет первый найденный элемент, обходя стек при помощи вспомогательного стека, и сохраняет исходный порядок:
public static boolean replaceFirst(Stack stack, T oldValue, T newValue) {
Stack buffer = new Stack();
boolean replaced = false;
while (!stack.empty()) {
T top = stack.pop();
if (!replaced && top.equals(oldValue)) {
buffer.push(newValue);
replaced = true;
break; // если хотим заменить только первый найденный элемент
} else {
buffer.push(top);
}
}
// вернуть элементы обратно
while (!buffer.empty()) {
stack.push(buffer.pop());
}
return replaced;
} Этот подход использует вспомогательный стек для временного хранения верхних элементов, затем восстанавливает порядок.
Критерии приёмки
- Метод push добавляет элемент на вершину и увеличивает размер стека.
- Метод pop удаляет и возвращает вершину; при пустом стеке должен выбрасываться EmptyStackException.
- Метод peek возвращает вершину без удаления.
- Метод search возвращает позицию относительно вершины (1-based) или -1 при отсутствии.
- Метод clear очищает весь стек; empty возвращает true после clear.
Тестовые случаи и приёмо-выходные условия
- Добавить N элементов, проверить размер, peek и toString.
- Удалить элементы до пустого состояния и проверить, что pop выбрасывает исключение при пустом стеке.
- Заменить элемент, находящийся в середине, и убедиться, что порядок остальных элементов восстановлен.
Чек-листы по ролям
Разработчик:
- Использовать обёртку или утилитный метод для операций, требующих временного удаления элементов.
- Обрабатывать исключения для pop и peek при пустом стеке.
- Предпочитать ArrayDeque если нужна лучшая производительность и нет требования синхронизации.
Код-ревьювер:
- Проверить корректность работы с границами (пустой стек, один элемент).
- Убедиться, что порядок восстановления элементов сохраняется.
- Оценить необходимость синхронизации.
Малое руководство по выбору структуры
Mermaid диаграмма выбора между стеком и альтернативами:
flowchart TD
A[Нужен ли доступ только к вершине?] -->|Да| B[Используйте стек/Deque]
A -->|Нет| C[Нужен случайный доступ?]
C -->|Да| D[Используйте List или массив]
C -->|Нет| E[Нужны операции в обе стороны?]
E -->|Да| F[Используйте Deque 'ArrayDeque/LinkedList']
E -->|Нет| G[Оцените требования и выберите подходящую структуру]Безопасность и конфиденциальность
Сам по себе стек — структура данных в памяти приложения. При хранении чувствительных данных учитывайте шифрование, минимизацию времени хранения и безопасную очистку памяти, если это критично для безопасности данных.
1-строчный глоссарий
- push — добавить элемент на вершину; pop — удалить и вернуть вершину; peek — посмотреть вершину без удаления; search — найти позицию относительно вершины (1-based); empty — проверить пустоту стека.
Важно: стек удобен для обратного порядка обработки и отката состояний, но не для случайного доступа.
Резюме:
- Stack в Java прост в использовании и совместим с Vector API.
- Для новых проектов рассмотрите ArrayDeque для стек-подобных задач, если не нужна синхронизация Vector.
- При обновлении глубоких элементов используйте вспомогательный стек или специализированные методы, чтобы сохранить порядок.
Сводка ключевых выводов:
- Стек реализует FILO; основной набор операций: push, pop, peek, search, empty.
- Для массовой очистки используйте clear(), для итераций — стандартные методы коллекций.
- Альтернативы: ArrayDeque, LinkedList, Deque-интерфейс.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone