Что такое стек java
Перейти к содержимому

Что такое стек java

  • автор:

Основы памяти в Java: Куча и Стек

Узнайте, как устроена память в Java: разбор работы Java-стека и кучи, особенностей управления памятью и роли сборщика мусора в данном процессе.

2 авг. 2023 · 7 минуты на чтение

Мы всё активнее применяем современные языки программирования, обеспечивающие нам возможность писать минимум кода для решения проблем. Возьмём за пример Java: он был разработан с целью максимального упрощения жизни программистов. Вам не приходится заботиться о памяти — ваши мысли целиком направлены на решение бизнес-задач. Однако это облегчение имеет свою цену.

В прошлой статье, мы обсудили общее устройство памяти в компьютере. А в этой статье мы сосредоточимся на том, как язык Java работает с памятью. Это включает в себя обзор стека и кучи в контексте Java, а также их отличия от общего представления. Мы также немного обсудим роль сборщика мусора в управлении памятью.

В данной статье не разбирается JMM. Углубиться в эту тему вы можете ознакомившись с дополнительными материалами в конце статьи.

Спонсор поста

Устройство памяти в программировании

Переходим к анализу ключевых концепций программирования, связанных с управлением памятью. Сначала обсудим стек и кучу — два фундаментальных механизма, лежащих в основе управления памятью. Затем рассмотрим их взаимодействие и особенности работы в процессе выполнения функций и методов.

Стек и куча представляют собой области памяти, используемые программами для хранения данных во время выполнения, но они используются по-разному и для разных целей.

Стек (Stack)

Стек — это область памяти, где функции хранят свои переменные и информацию для выполнения. Представьте стек как физическую стопку подносов в ресторане: вы можете добавить поднос сверху (push) или взять верхний поднос (pop). Аналогично, когда функция вызывается, ее локальные переменные и информация о вызове кладутся на стек сверху, и забираются сверху (уничтожаются), когда функция завершает работу.

Стек обеспечивает быстрый доступ к данным и автоматическое управление памятью, но имеет ограниченный размер. Если ваша программа использует больше стековой памяти, чем доступно, программа может завершиться с ошибкой переполнения стека.

Куча (Heap)

Куча — это область памяти, где данные могут быть размещены динамически во время выполнения программы. В отличие от стека, где данные удаляются автоматически после выхода из функции, данные в куче остаются, пока их явно не удалить.

Это делает кучу идеальным местом для хранения данных, которые должны пережить вызов функции, или для работы с большими объемами данных. Однако работа с кучей требует аккуратного управления: если вы не удаляете объекты, когда они больше не нужны, может произойти утечка памяти, что в конечном итоге может привести к исчерпанию доступной памяти.

Для удобства визуализируем стек и кучу. Серые объекты потеряли свою ссылку из стека, их необходимо удалить, чтобы освободить память для новых объектов.

Объект может содержать методы, и эти методы могут содержать локальные переменные. Эти локальные переменные также хранятся в стеке потоков, даже если объект, которому принадлежит метод, хранится в куче.

Стек

Когда функция вызывается, для нее выделяется блок памяти на вершине стека. Этот блок памяти, известный как «фрейм стека», содержит пространство для всех локальных переменных функции, а также информацию, такую как возвращаемый адрес: адрес в коде, к которому следует вернуться после завершения функции.

Когда функция вызывает другую функцию, для новой функции выделяется свой фрейм стека, и она становится текущей активной функцией. Когда функция завершает свою работу, ее фрейм стека удаляется, и управление возвращается обратно в вызывающую функцию.

Синхронизация в Java служит для контроля доступа нескольких потоков к общим ресурсам. Синхронизация может быть реализована с использованием ключевого слова synchronized или специальных классов, таких как ReentrantLock или Semaphore .

Сборщик мусора в Java работает в многопоточной среде и способен обрабатывать объекты из всех потоков. Однако следует быть внимательным с долгоживущими объектами и ресурсами, которые могут заблокировать сборщик мусора.

Заключение

В контексте программирования, стек и куча играют различные, но важные роли. Стек служит для хранения информации о функциях и их вызовах, в то время как куча используется для динамического выделения памяти.

В случае с Java, управление памятью становится еще более интересным благодаря сборщику мусора, который автоматически освобождает неиспользуемую память, и разделению памяти на Heap Space и Stack Space. Эти особенности делают язык Java удобным для работы, но также требуют осознанного использования памяти для предотвращения проблем с производительностью.

В заключение, управление памятью — это сложная, но неотъемлемая часть работы с компьютерами и программным обеспечением. Понимание основ и принципов управления памятью может помочь разработчикам создавать более эффективные и надежные приложения.

Дополнительные материалы

  • Habr: Глубокое погружение в Java Memory Model
  • Habr: Откуда растут ноги у Java Memory Model

Реализация stack в Java

Stack — это линейная структура данных, которая следует принципу LIFO (последний пришел, первый ушел). Это означает, что объекты могут быть вставлены или удалены только с одного конца, также называемого вершиной.

Stack поддерживает следующие операции:

  • push вставляет элемент на вершину stack (т. е. над его текущим верхним элементом).
  • pop удаляет объект из вершины stack и возвращает этот объект из функции. Размер stack будет уменьшен на единицу.
  • isEmpty проверяет, пуст stack или нет.
  • isFull проверяет, заполнен ли stack или нет.
  • peek возвращает объект наверху stack, не удаляя его из stack и не изменяя стек каким-либо образом.
  • size возвращает общее количество элементов, присутствующих в stack.

Реализация stack с использованием массива

Стек может быть легко реализован в виде массива. Ниже приведена реализация stack в Java с использованием массива:

Что такое стек java

Мега-статья, потому что про очереди я так и не врубался на многочасовых лекциях и примерах, прочитав за 15 минут эту обычную статью все разложилось по полочкам, Большое спасибо!

Магсумова Диана Уровень 108 Expert
14 августа 2022
Прекрасная статья! )))) Благодарю))))
Евгений Т. Уровень 39
19 мая 2022
Ошибка в тексте «И со многими ИХ них «.
Жора Нет Уровень 39
30 апреля 2022

Из лекций ничего нового не почерпнул, кроме определения сложности алгоритмов. Все эти Стэки и Очереди приходилось самому находить и изучать при решении некоторых задач. Так вот в чем суть этих лекций? Я понимаю, если бы углублялись в изучении этих структур. А так получается я уже о них знаю больше, чем мне только что поверхностно рассказали.

Bulkin Уровень 40
10 ноября 2021
откуда столько времени найти такие книги читать?
Anonymous #2491313 Уровень 35
25 апреля 2021
Почему доставание элемента из очереди называется pull, а не pop?
Арман Уровень 37
14 апреля 2021
а на ее основе нередко строятся более сложныХ структуры данных.
5 апреля 2021

Я не понял откуда взялись эти классы и что они делают в примере про стек: game.setDeck(deck); game.setGraveyard(graveyard);

Иван Уровень 41
28 декабря 2020
Дайте несколько задач на очереди!
�� Виктор Уровень 20 Expert
6 ноября 2020

For the Alliance! Спасибо за статью, достаточно доступно, понятно и с хорошими примерами. Можно на эту тему ещё почитать следующие статьи: Стек-трейс Java. Stack Trace и с чем его едят. p.s. Если нужна, упомянутая в статье, книга Роберта Лафоре на русском языке в PDF формате с интерактивным оглавлением, то пишите, поделюсь ; )

Как работает стек в Java

Java разработчик: как стать за месяц?

7 фактов про Java

Java — очень сложно, так говорят… Правда ли это?

Зачем Java разработчикам читать книги по Java

Исключения в Java: что это и как их использовать

Программирование — это не только о том, как создавать функциональные приложения, но и о том, как эффективно управлять данными. И одним из ключевых инструментов, которые помогают нам с этим, является структура данных под названием «стек». Давайте более подробно разберемся в его сути и том, как он работает. Представьте, что у вас есть набор книг, которые вы храните в виде стопки. Как только вы кладете новую книгу, она автоматически становится на вершину стопки, и единственный способ достать книгу — это снять ее с вершины. Именно так работает стек java.

В программировании — последний добавленный элемент всегда будет первым, который будет удален. Рассмотрим принципы его работы, чтобы понять, как он может быть полезен нам в разработке ПО.

Описание структуры данных

Стек — это такая структура данных, которая работает по принципу «последний вошел, первый вышел» (LIFO — Last In, First Out). Вы наверняка видели стопку книг или тарелок в кафе, где новые элементы кладут сверху, а чтобы достать нужный, вы снимаете его именно с верхушки стопки.

В Java стек можно представить с помощью класса Stack. Основные операции, которые можно выполнять со стеком, включают добавление элемента на вершину стека (push) и удаление элемента с вершины (pop). Если вы хотите положить новый элемент на стек, используйте операцию push, а если хотите извлечь элемент, то используйте операцию pop.

Определение стека в Java

Реализация стека в Java достаточно проста и удобна. Вы можете создать объект класса Stack, а затем использовать методы push и pop для управления элементами стека. Важно помнить, что при использовании стека нужно следить за порядком операций, чтобы не нарушить принцип LIFO.

Например, вот как вы можете создать стек в Java:

import java.util.Stack; public class Main < public static void main(String[] args) < Stackstack = new Stack<>(); stack.push(1); // Добавляем элемент 1 на вершину стека stack.push(2); // Добавляем элемент 2 на вершину стека stack.push(3); // Добавляем элемент 3 на вершину стека int top = stack.pop(); // Извлекаем элемент с вершины стека (3) System.out.println(top); // Выводим: 3 > >

В данном примере мы создаем стек целых чисел (Stack) и добавляем в него три элемента. Затем мы извлекаем элемент с вершины стека и выводим его значение на экран.

Реализация стека в Java предоставляет удобные методы для управления данными и может быть полезной во многих ситуациях программирования.

Примеры использования стека в Java

Давайте представим, что мы пишем программу, которая проверяет правильность расстановки скобок в математическом выражении. Например, у нас есть выражение: «(2 + 3) * (4 — 1)». Мы можем использовать стек, чтобы проверить, что все скобки в выражении сбалансированы (открывающая скобка имеет соответствующую закрывающую скобку). Вот как это можно сделать:

import java.util.Stack; public class BracketChecker < public static boolean isBalanced(String expression) < Stackstack = new Stack<>(); for (char c : expression.toCharArray()) < if (c == '(') < stack.push(c); // Если встретили открывающую скобку, кладем ее в стек >else if (c == ')') < if (stack.isEmpty()) < return false; // Если встретили закрывающую скобку, но стек пуст, значит скобки несбалансированы >stack.pop(); // Если встретили закрывающую скобку, удаляем соответствующую открывающую скобку из стека > > return stack.isEmpty(); // Если стек пуст, значит все скобки сбалансированы > public static void main(String[] args) < String expression = "(2 + 3) * (4 - 1)"; boolean isBalanced = isBalanced(expression); System.out.println("Выражение сбалансировано? " + isBalanced); >>

В этом примере мы создаем стек символов (Stack) и проходим по каждому символу в выражении. Если встречаем открывающую скобку, кладем ее в стек. Если встречаем закрывающую скобку, проверяем, есть ли соответствующая открывающая скобка в стеке. Если стек пуст или открывающая скобка несоответствующая, то выражение несбалансированно. В конце проверяем, что стек пуст, чтобы убедиться в сбалансированности скобок.

�� Java Start: Ваш путь в программирование!

�� Условия:

  • Онлайн курс
  • Неограниченный доступ к лекциям и видео-урокам
  • Без проверки заданий
  • Помощь в чате Slack

Срок обучения:

Проходите курс за 2-4 недели.

Но рассмотрим пример посложнее:

Предположим, у вас есть задача реализации системы отката (undo) для текстового редактора. Вы хотите, чтобы пользователь мог выполнять операции над текстом (например, вставка, удаление, замена) и иметь возможность отменить эти операции в обратном порядке.

Вы можете использовать стек для хранения выполненных операций. Каждая операция будет представлена объектом, содержащим информацию о типе операции и ее параметрах. При выполнении операции вы будете добавлять ее в стек, а при отмене операции — удалять из стека и выполнять обратную операцию. Это позволяет нам отменять предыдущие действия пользователя и восстанавливать предыдущее состояние текста.

Вот пример кода для реализации системы отката с использованием стека:

import java.util.Stack; public class TextEditor < private StringBuilder text; private StackoperationStack; public TextEditor() < text = new StringBuilder(); operationStack = new Stack<>(); > public void insertText(String newText) < Operation operation = new InsertOperation(newText); operation.execute(text); operationStack.push(operation); >public void deleteText(int startIndex, int endIndex) < String deletedText = text.substring(startIndex, endIndex); Operation operation = new DeleteOperation(startIndex, deletedText); operation.execute(text); operationStack.push(operation); >public void undo() < if (!operationStack.isEmpty()) < Operation operation = operationStack.pop(); operation.undo(text); >> private abstract class Operation < public abstract void execute(StringBuilder text); public abstract void undo(StringBuilder text); >private class InsertOperation extends Operation < private String newText; public InsertOperation(String newText) < this.newText = newText; >public void execute(StringBuilder text) < text.append(newText); >public void undo(StringBuilder text) < int startIndex = text.length() - newText.length(); text.delete(startIndex, text.length()); >> private class DeleteOperation extends Operation < private int startIndex; private String deletedText; public DeleteOperation(int startIndex, String deletedText) < this.startIndex = startIndex; this.deletedText = deletedText; >public void execute(StringBuilder text) < text.delete(startIndex, startIndex + deletedText.length()); >public void undo(StringBuilder text) < text.insert(startIndex, deletedText); >> >

В этом примере мы используем стек operationStack для хранения выполненных операций.

Надеемся, этот пример помог вам лучше понять сложные применения стека в Java!

Сравнение стека с другими структурами данных

Структуры данных являются важной частью программирования и позволяют эффективно хранить и организовывать данные. Три популярные структуры данных в Java — стек, очередь и дерево — имеют свои особенности и применения.

Стек — это структура данных, в которой элементы добавляются и удаляются только с одного конца, называемого вершиной. Последний добавленный элемент всегда будет первым, который будет удален. Пример использования стека включает управление временными данными, отмену действий и выполнение операций в обратном порядке.

�� Подпишись на наш Ютуб-канал! ��Полезные видео для программистов уже ждут тебя!

�� Выбери свой курс программирования! �� Путь к карьере программиста начинается здесь!

Очередь — это структура данных, в которой элементы добавляются в один конец — “конец очереди”, и удаляются с другого конца, называемого “началом очереди”. Первый добавленный элемент будет первым, который будет удален. Очередь полезна, когда нужно обрабатывать элементы в порядке их добавления, например, в системах обработки задач, веб-серверах или при обработке событий.

Дерево — это иерархическая структура данных, состоящая из узлов, связанных между собой ребрами. У каждого узла может быть один родитель и ноль или более дочерних узлов. Деревья используются для представления иерархических отношений, таких как файловые системы или иерархии категорий. Они могут иметь различные типы, такие как бинарные деревья или двоичные поисковые деревья.

Давайте рассмотрим их отличия подробнее.

Структура данных Основной принцип Примеры применения
Стек LIFO (последний вошел, первый вышел) Управление временными данными, отмена действий, выполнение операций в обратном порядке
Очередь FIFO (первый вошел, первый вышел) Системы обработки задач, веб-серверы, обработка событий
Дерево Иерархическая структура данных с родительскими и дочерними узлами Файловые системы, иерархии категорий, поисковые структуры

Как видим, все эти три структуры данных имеют разные принципы работы и применения. Стек используется для управления временными данными и выполнения операций в обратном порядке, очередь — для обработки элементов в порядке добавления, а дерево — для представления иерархических отношений. Выбор структуры данных зависит от конкретной задачи и требований программы.

Заключение

Понимание принципов работы стека позволяет программистам организовывать и структурировать данные таким образом, чтобы удовлетворять требованиям конкретных задач. Это помогает оптимизировать процессы, улучшить производительность и создавать более надежное ПО. Поэтому понимание стека и его применений является неотъемлемой частью навыков программиста и способствует развитию и повышению его профессионализма.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *