Estrutura de Dados Pilha em Java
Uma Stack é uma estrutura de dados que segue o princípio Last In, First Out (LIFO). O mesmo princípio se aplica a uma Deque, que foi abordada anteriormente, e desenvolvedores Java recomendam o uso de uma Deque quando uma estrutura de dados precisa operar sob o princípio LIFO. A estrutura de dados Stack está obsoleta e não é recomendada no desenvolvimento Java moderno.
No entanto, algumas coleções não são mais recomendadas e foram descontinuadas.
Descontinuado
Quando um elemento é marcado como descontinuado, significa que os autores da biblioteca ou linguagem de programação aconselham evitar seu uso em novos códigos e recomendam a adoção de novos métodos, classes ou abordagens que possam fornecer soluções mais seguras, eficientes ou funcionais.
Um exemplo é a classe Vector em Java. Seus métodos foram descontinuados em favor de coleções mais modernas como ArrayList e LinkedList. Se um programador ainda utilizar métodos de Vector, o compilador pode emitir um aviso de que esses métodos estão obsoletos.
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 utilizar uma estrutura de dados como Stack, mas iremos discuti-la neste capítulo porque é uma estrutura de dados interessante utilizada, por exemplo, na memória Stack em Java.
Pilha
Direto ao ponto, veja os métodos da classe Stack:
Métodos
push(E element): 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); } }
A adição é realizada da mesma forma que em ArrayList, portanto, vamos analisar 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() remove o último elemento adicionado à pilha. É exatamente assim que o princípio LIFO funciona.
Também é possível visualizar 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, visualiza-se o elemento do topo na pilha.
Utilização
Considere um exemplo de uso da estrutura de dados Stack para navegação entre páginas em um navegador (aqueles botões de avançar e voltar que são frequentemente utilizados).
Vamos planejar a implementação do histórico do navegador e implementar métodos para dois botões (goBack() e goForward()).
Caso não esteja certo a quais botões me refiro, trata-se destes botões de navegação:
Vamos implementar uma classe que possui métodos para operar esses dois botões utilizando a estrutura de dados Stack.
Como Vai Funcionar
Você terá duas pilhas e uma variável String. A primeira pilha irá armazenar os links que navegamos ao clicar na seta "voltar". A segunda pilha irá armazenar os links que você navega ao clicar na seta "avançar". Você também terá uma variável String que armazena o link da página atual.
Nesta classe, haverá quatro métodos: visitPage(), goBack(), goForward() e getCurrentPage(). Vamos analisá-los passo a passo.
O método visitPage() irá redirecionar para a URL especificada no parâmetro. Ao ir para uma nova página, o link antigo será adicionado ao backStack. O forwardStack será limpo ao navegar 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); } }
Dessa forma, podemos retornar à página anterior ao navegar para uma nova página.
Vamos implementar o método para voltar. Ele funcionará assim: adicionamos o link atual ao forwardStack, depois removemos esse link do backStack e atribuímos ao currentUrl.
Vamos ver 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."); } }
Lembro que o método pop() remove o elemento do topo da pilha e o retorna. Portanto, ao utilizar este método, atribuímos imediatamente o valor da URL à variável currentUrl.
Também verificamos se a backStack não está vazia; caso contrário, não será possível voltar para o link anterior (simplesmente porque ele não existirá). Se a pilha estiver vazia, exibimos uma mensagem correspondente.
Da mesma forma, implementamos o método para navegação para a página seguinte. Apenas trocamos os elementos na 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 de currentUrl.
Testes
Em seguida, testaremos tudo isso no método main. Utilizaremos o método visitPage() três vezes para garantir que esses links sejam salvos no histórico. Depois, utilizaremos o método goBack() duas vezes, seguido pelo método goForward() uma vez, para verificar a funcionalidade dos métodos implementados.
Durante esse processo, acompanharemos nosso estado utilizando o método getCurrentPage(). Você pode executar o código abaixo e também tentar inserir mais links e utilizar 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; } }
Lembre-se de que a classe Stack é obsoleta e não é recomendada para uso no desenvolvimento moderno em Java. Em vez disso, é melhor utilizar Deque, que é uma alternativa mais eficiente. Neste exemplo, Stack é implementada com base no princípio LIFO, e você também pode implementar Deque, pois é uma fila de duas extremidades que suporta tanto os princípios FIFO quanto LIFO.
1. Qual é o princípio fundamental de uma estrutura de dados Stack?
2. Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?
3. Qual das seguintes coleções Java é considerada uma alternativa mais moderna ao Stack?
4. Em Java, o que o método pop() de uma Stack retorna?
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
What are the main differences between Stack and Deque in Java?
Can you show how to implement the same browser history example using Deque?
Why is Stack considered obsolete in Java?
Incrível!
Completion taxa melhorada para 4
Estrutura de Dados Pilha em Java
Deslize para mostrar o menu
Uma Stack é uma estrutura de dados que segue o princípio Last In, First Out (LIFO). O mesmo princípio se aplica a uma Deque, que foi abordada anteriormente, e desenvolvedores Java recomendam o uso de uma Deque quando uma estrutura de dados precisa operar sob o princípio LIFO. A estrutura de dados Stack está obsoleta e não é recomendada no desenvolvimento Java moderno.
No entanto, algumas coleções não são mais recomendadas e foram descontinuadas.
Descontinuado
Quando um elemento é marcado como descontinuado, significa que os autores da biblioteca ou linguagem de programação aconselham evitar seu uso em novos códigos e recomendam a adoção de novos métodos, classes ou abordagens que possam fornecer soluções mais seguras, eficientes ou funcionais.
Um exemplo é a classe Vector em Java. Seus métodos foram descontinuados em favor de coleções mais modernas como ArrayList e LinkedList. Se um programador ainda utilizar métodos de Vector, o compilador pode emitir um aviso de que esses métodos estão obsoletos.
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 utilizar uma estrutura de dados como Stack, mas iremos discuti-la neste capítulo porque é uma estrutura de dados interessante utilizada, por exemplo, na memória Stack em Java.
Pilha
Direto ao ponto, veja os métodos da classe Stack:
Métodos
push(E element): 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); } }
A adição é realizada da mesma forma que em ArrayList, portanto, vamos analisar 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() remove o último elemento adicionado à pilha. É exatamente assim que o princípio LIFO funciona.
Também é possível visualizar 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, visualiza-se o elemento do topo na pilha.
Utilização
Considere um exemplo de uso da estrutura de dados Stack para navegação entre páginas em um navegador (aqueles botões de avançar e voltar que são frequentemente utilizados).
Vamos planejar a implementação do histórico do navegador e implementar métodos para dois botões (goBack() e goForward()).
Caso não esteja certo a quais botões me refiro, trata-se destes botões de navegação:
Vamos implementar uma classe que possui métodos para operar esses dois botões utilizando a estrutura de dados Stack.
Como Vai Funcionar
Você terá duas pilhas e uma variável String. A primeira pilha irá armazenar os links que navegamos ao clicar na seta "voltar". A segunda pilha irá armazenar os links que você navega ao clicar na seta "avançar". Você também terá uma variável String que armazena o link da página atual.
Nesta classe, haverá quatro métodos: visitPage(), goBack(), goForward() e getCurrentPage(). Vamos analisá-los passo a passo.
O método visitPage() irá redirecionar para a URL especificada no parâmetro. Ao ir para uma nova página, o link antigo será adicionado ao backStack. O forwardStack será limpo ao navegar 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); } }
Dessa forma, podemos retornar à página anterior ao navegar para uma nova página.
Vamos implementar o método para voltar. Ele funcionará assim: adicionamos o link atual ao forwardStack, depois removemos esse link do backStack e atribuímos ao currentUrl.
Vamos ver 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."); } }
Lembro que o método pop() remove o elemento do topo da pilha e o retorna. Portanto, ao utilizar este método, atribuímos imediatamente o valor da URL à variável currentUrl.
Também verificamos se a backStack não está vazia; caso contrário, não será possível voltar para o link anterior (simplesmente porque ele não existirá). Se a pilha estiver vazia, exibimos uma mensagem correspondente.
Da mesma forma, implementamos o método para navegação para a página seguinte. Apenas trocamos os elementos na 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 de currentUrl.
Testes
Em seguida, testaremos tudo isso no método main. Utilizaremos o método visitPage() três vezes para garantir que esses links sejam salvos no histórico. Depois, utilizaremos o método goBack() duas vezes, seguido pelo método goForward() uma vez, para verificar a funcionalidade dos métodos implementados.
Durante esse processo, acompanharemos nosso estado utilizando o método getCurrentPage(). Você pode executar o código abaixo e também tentar inserir mais links e utilizar 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; } }
Lembre-se de que a classe Stack é obsoleta e não é recomendada para uso no desenvolvimento moderno em Java. Em vez disso, é melhor utilizar Deque, que é uma alternativa mais eficiente. Neste exemplo, Stack é implementada com base no princípio LIFO, e você também pode implementar Deque, pois é uma fila de duas extremidades que suporta tanto os princípios FIFO quanto LIFO.
1. Qual é o princípio fundamental de uma estrutura de dados Stack?
2. Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?
3. Qual das seguintes coleções Java é considerada uma alternativa mais moderna ao Stack?
4. Em Java, o que o método pop() de uma Stack retorna?
Obrigado pelo seu feedback!