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
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!