Pilha
Uma Stack
é outra estrutura de dados que opera no princípio Último a Entrar, Primeiro a Sair (LIFO). O mesmo princípio pode ser aplicado a um Deque
, que você aprendeu anteriormente, e desenvolvedores Java recomendam usar Deque
se houver necessidade de uma estrutura de dados que opere no princípio LIFO. A estrutura de dados Stack
está obsoleta.
Obsoleto
Quando um elemento é marcado como obsoleto, significa que os autores da biblioteca ou linguagem de programação aconselham evitar o seu uso em novos códigos e recomendam a adoção de métodos, classes ou abordagens novas que possam fornecer soluções mais seguras, eficientes ou funcionais.
Um exemplo é a classe Vector
em Java. Seus métodos foram depreciados em favor de coleções mais modernas como ArrayList
e LinkedList
. Se um programador ainda utiliza métodos Vector
, o compilador pode emitir um aviso de que esses métodos estão depreciados.
Exemplo em Java:
main.java
12345678910111213141516package com.example; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<String> vector = new Vector<>(); // Adding an element (this method is deprecated) vector.addElement("Item"); // Compiler warning about the deprecated method // Note: 'addElement(java.lang.Object)' is deprecated. System.out.println(vector.get(0)); } }
Portanto, não é recomendado usar uma estrutura de dados como Pilha (Stack), mas discutiremos isso neste capítulo porque é uma estrutura de dados interessante, utilizada, por exemplo, na memória Stack do Java.
Pilha
Direto ao assunto, vamos olhar os métodos da classe Stack
:
Métodos
push(E element)
(adição): Adiciona um elemento no topo da pilha.
main.java
123456789101112package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); } }
Adicionar é feito da mesma forma que em ArrayList
, então vamos olhar imediatamente este método em combinação com o método pop()
:
pop()
: Remove e retorna o elemento do topo da pilha.
main.java
1234567891011121314package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); stack.pop(); System.out.println("Stack after the `pop()` method: " + stack); } }
Este método remove um elemento do topo da pilha. Observe que o método pop()
elimina o elemento adicionado por último da pilha. É exatamente assim que o princípio LIFO (Last In, First Out - Último a Entrar, Primeiro a Sair) funciona.
Também podemos verificar qual elemento está no topo da pilha:
- Peek: Retorna o elemento do topo da pilha sem removê-lo.
main.java
123456789101112131415package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); String top = stack.peek(); System.out.println("Top element of the stack: " + top); System.out.println("Stack after the `peek()` method: " + stack); } }
Com este método, verificamos o elemento do topo da pilha.
Uso
Vamos considerar um exemplo de utilização da estrutura de dados pilha para navegar entre páginas em um navegador (aqueles botões de avançar e voltar que frequentemente usamos).
Vamos planejar a implementação do histórico do navegador e implementar métodos para dois botões (goBack()
e goForward()
).
Se você não tem certeza de quais botões estou me referindo, estou falando sobre estes botões:
Vamos implementar uma classe que possui métodos para operar estes dois botões, utilizando a estrutura de dados Stack
.
Como vai funcionar:
-
Teremos duas pilhas e uma variável
String
. A primeira pilha vai armazenar os links que navegamos ao clicar na seta "back
". A segunda pilha vai armazenar os links que navegamos ao clicar na seta "forward
". Também teremos uma variávelString
que armazena o link da página atual. -
Nesta classe, haverá quatro métodos:
visitPage()
,goBack()
,goForward()
egetCurrentPage()
. Vamos passar por eles passo a passo: -
O método
visitPage()
irá nos redirecionar para a URL especificada no parâmetro. Ao nos movermos para uma nova página, o link antigo será adicionado àbackStack
. AforwardStack
será limpa, visto que estamos nos movendo para uma nova página. Vamos ver a implementação no código:
BrowserHistory.java
1234567891011121314151617181920212223242526import java.util.Stack; public class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } }
- Desta forma, podemos retornar à página anterior ao navegar para uma nova página.
Vamos implementar o método para voltar. Funcionará assim: adicionamos o link atual à
forwardStack
, depois removemos este link dabackStack
e o atribuímos acurrentUrl
. Vejamos a implementação no código:
BrowserHistory.java
12345678910public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } }
-
Eu vou lembrá-lo de que o método
pop()
remove o elemento do topo da pilha e o retorna. Portanto, ao usar este método, nós imediatamente atribuímos o valor da URL à variávelcurrentUrl
. Também verificamos para garantir que abackStack
não está vazia; caso contrário, não poderemos voltar ao link anterior (simplesmente porque ele não estará lá). Se a pilha estiver vazia, nós exibimos uma mensagem correspondente. -
Da mesma forma, implementamos o método para navegar para a página seguinte. Nós simplesmente trocamos os elementos da pilha:
BrowserHistory.java
12345678910public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } }
- Agora, tudo o que resta é implementar o método
getCurrentPage()
, que simplesmente retornará o valor decurrentUrl
.
Teste
A seguir, vamos testar tudo isso no método main
. Usaremos o método visitPage()
três vezes para garantir que esses links sejam salvos no histórico. Em seguida, usaremos o método goBack()
duas vezes, seguido do método goForward()
uma vez, para verificar a funcionalidade dos métodos escritos.
Durante esse processo, acompanharemos nosso estado usando o método getCurrentPage()
. Você pode executar o código abaixo e também tentar inserir mais links e usar diferentes métodos para testar a funcionalidade desta classe:
Main.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778package com.example; import java.util.Stack; class Main { public static void main(String[] args) { BrowserHistory browser = new BrowserHistory(); System.out.println("Default page: " + browser.getCurrentPage()); browser.visitPage("https://codefinity.com/courses/tracks/7dfbcd35-5cde-49d3-80f1-bf1096487903"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/e66c57b4-5f36-43b2-bd3b-e1398044fcab"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/1585fb29-47cd-47a6-9fb3-5b391cad24e0"); System.out.println("Current Page after visiting 3 pages: " + browser.getCurrentPage()); browser.goBack(); browser.goBack(); System.out.println("Current Page after going back 2 times: " + browser.getCurrentPage()); browser.goForward(); System.out.println("Current Page after going forward: " + browser.getCurrentPage()); } } class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } } public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } } public String getCurrentPage() { return currentUrl; } }
Nota
Se o grande número de saídas no console é incômodo, você pode remover as operações de impressão no console dos métodos, deixando apenas as saídas intermediárias na tela.
Lembre-se de que a classe Stack
é obsoleta e é melhor usar Deque
em vez disso. Neste exemplo, Stack
é implementado baseado no princípio LIFO (último a entrar, primeiro a sair), e também podemos implementar Deque
, já que é uma fila de duas pontas que pode operar baseada nos princípios FIFO e LIFO (primeiro a entrar, primeiro a sair).
Se encontrar dificuldades para entender o exemplo ou o código em geral, sinta-se à vontade para clicar em "Não está claro?" e fazer sua pergunta. Farei o meu melhor para ajudá-lo a entender o material o mais rápido possível!
Além disso, não se esqueça de que você pode aproveitar o recurso "Conversar Com a Comunidade", onde usuários como você estão prontos para ajudá-lo!
1. Qual é o princípio principal de uma estrutura de dados do tipo Pilha
?
2. Qual interface Java a classe Stack
implementa?
3. Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?
4. Qual das seguintes coleções Java é considerada uma alternativa mais moderna para Stack
?
5. No Java, o que o método pop()
de um Stack
retornará?
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Awesome!
Completion rate improved to 4
Pilha
Deslize para mostrar o menu
Uma Stack
é outra estrutura de dados que opera no princípio Último a Entrar, Primeiro a Sair (LIFO). O mesmo princípio pode ser aplicado a um Deque
, que você aprendeu anteriormente, e desenvolvedores Java recomendam usar Deque
se houver necessidade de uma estrutura de dados que opere no princípio LIFO. A estrutura de dados Stack
está obsoleta.
Obsoleto
Quando um elemento é marcado como obsoleto, significa que os autores da biblioteca ou linguagem de programação aconselham evitar o seu uso em novos códigos e recomendam a adoção de métodos, classes ou abordagens novas que possam fornecer soluções mais seguras, eficientes ou funcionais.
Um exemplo é a classe Vector
em Java. Seus métodos foram depreciados em favor de coleções mais modernas como ArrayList
e LinkedList
. Se um programador ainda utiliza métodos Vector
, o compilador pode emitir um aviso de que esses métodos estão depreciados.
Exemplo em Java:
main.java
12345678910111213141516package com.example; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<String> vector = new Vector<>(); // Adding an element (this method is deprecated) vector.addElement("Item"); // Compiler warning about the deprecated method // Note: 'addElement(java.lang.Object)' is deprecated. System.out.println(vector.get(0)); } }
Portanto, não é recomendado usar uma estrutura de dados como Pilha (Stack), mas discutiremos isso neste capítulo porque é uma estrutura de dados interessante, utilizada, por exemplo, na memória Stack do Java.
Pilha
Direto ao assunto, vamos olhar os métodos da classe Stack
:
Métodos
push(E element)
(adição): Adiciona um elemento no topo da pilha.
main.java
123456789101112package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); } }
Adicionar é feito da mesma forma que em ArrayList
, então vamos olhar imediatamente este método em combinação com o método pop()
:
pop()
: Remove e retorna o elemento do topo da pilha.
main.java
1234567891011121314package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); stack.pop(); System.out.println("Stack after the `pop()` method: " + stack); } }
Este método remove um elemento do topo da pilha. Observe que o método pop()
elimina o elemento adicionado por último da pilha. É exatamente assim que o princípio LIFO (Last In, First Out - Último a Entrar, Primeiro a Sair) funciona.
Também podemos verificar qual elemento está no topo da pilha:
- Peek: Retorna o elemento do topo da pilha sem removê-lo.
main.java
123456789101112131415package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); String top = stack.peek(); System.out.println("Top element of the stack: " + top); System.out.println("Stack after the `peek()` method: " + stack); } }
Com este método, verificamos o elemento do topo da pilha.
Uso
Vamos considerar um exemplo de utilização da estrutura de dados pilha para navegar entre páginas em um navegador (aqueles botões de avançar e voltar que frequentemente usamos).
Vamos planejar a implementação do histórico do navegador e implementar métodos para dois botões (goBack()
e goForward()
).
Se você não tem certeza de quais botões estou me referindo, estou falando sobre estes botões:
Vamos implementar uma classe que possui métodos para operar estes dois botões, utilizando a estrutura de dados Stack
.
Como vai funcionar:
-
Teremos duas pilhas e uma variável
String
. A primeira pilha vai armazenar os links que navegamos ao clicar na seta "back
". A segunda pilha vai armazenar os links que navegamos ao clicar na seta "forward
". Também teremos uma variávelString
que armazena o link da página atual. -
Nesta classe, haverá quatro métodos:
visitPage()
,goBack()
,goForward()
egetCurrentPage()
. Vamos passar por eles passo a passo: -
O método
visitPage()
irá nos redirecionar para a URL especificada no parâmetro. Ao nos movermos para uma nova página, o link antigo será adicionado àbackStack
. AforwardStack
será limpa, visto que estamos nos movendo para uma nova página. Vamos ver a implementação no código:
BrowserHistory.java
1234567891011121314151617181920212223242526import java.util.Stack; public class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } }
- Desta forma, podemos retornar à página anterior ao navegar para uma nova página.
Vamos implementar o método para voltar. Funcionará assim: adicionamos o link atual à
forwardStack
, depois removemos este link dabackStack
e o atribuímos acurrentUrl
. Vejamos a implementação no código:
BrowserHistory.java
12345678910public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } }
-
Eu vou lembrá-lo de que o método
pop()
remove o elemento do topo da pilha e o retorna. Portanto, ao usar este método, nós imediatamente atribuímos o valor da URL à variávelcurrentUrl
. Também verificamos para garantir que abackStack
não está vazia; caso contrário, não poderemos voltar ao link anterior (simplesmente porque ele não estará lá). Se a pilha estiver vazia, nós exibimos uma mensagem correspondente. -
Da mesma forma, implementamos o método para navegar para a página seguinte. Nós simplesmente trocamos os elementos da pilha:
BrowserHistory.java
12345678910public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } }
- Agora, tudo o que resta é implementar o método
getCurrentPage()
, que simplesmente retornará o valor decurrentUrl
.
Teste
A seguir, vamos testar tudo isso no método main
. Usaremos o método visitPage()
três vezes para garantir que esses links sejam salvos no histórico. Em seguida, usaremos o método goBack()
duas vezes, seguido do método goForward()
uma vez, para verificar a funcionalidade dos métodos escritos.
Durante esse processo, acompanharemos nosso estado usando o método getCurrentPage()
. Você pode executar o código abaixo e também tentar inserir mais links e usar diferentes métodos para testar a funcionalidade desta classe:
Main.java
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778package com.example; import java.util.Stack; class Main { public static void main(String[] args) { BrowserHistory browser = new BrowserHistory(); System.out.println("Default page: " + browser.getCurrentPage()); browser.visitPage("https://codefinity.com/courses/tracks/7dfbcd35-5cde-49d3-80f1-bf1096487903"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/e66c57b4-5f36-43b2-bd3b-e1398044fcab"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/1585fb29-47cd-47a6-9fb3-5b391cad24e0"); System.out.println("Current Page after visiting 3 pages: " + browser.getCurrentPage()); browser.goBack(); browser.goBack(); System.out.println("Current Page after going back 2 times: " + browser.getCurrentPage()); browser.goForward(); System.out.println("Current Page after going forward: " + browser.getCurrentPage()); } } class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } } public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } } public String getCurrentPage() { return currentUrl; } }
Nota
Se o grande número de saídas no console é incômodo, você pode remover as operações de impressão no console dos métodos, deixando apenas as saídas intermediárias na tela.
Lembre-se de que a classe Stack
é obsoleta e é melhor usar Deque
em vez disso. Neste exemplo, Stack
é implementado baseado no princípio LIFO (último a entrar, primeiro a sair), e também podemos implementar Deque
, já que é uma fila de duas pontas que pode operar baseada nos princípios FIFO e LIFO (primeiro a entrar, primeiro a sair).
Se encontrar dificuldades para entender o exemplo ou o código em geral, sinta-se à vontade para clicar em "Não está claro?" e fazer sua pergunta. Farei o meu melhor para ajudá-lo a entender o material o mais rápido possível!
Além disso, não se esqueça de que você pode aproveitar o recurso "Conversar Com a Comunidade", onde usuários como você estão prontos para ajudá-lo!
1. Qual é o princípio principal de uma estrutura de dados do tipo Pilha
?
2. Qual interface Java a classe Stack
implementa?
3. Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?
4. Qual das seguintes coleções Java é considerada uma alternativa mais moderna para Stack
?
5. No Java, o que o método pop()
de um Stack
retornará?
Obrigado pelo seu feedback!