Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Estrutura de Dados Pilha em Java | Estruturas de Dados Avançadas em Java
Estruturas de Dados em Java

bookEstrutura 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

Main.java

copy
12345678910111213141516
package 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

Main.java

copy
123456789101112
package 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

Main.java

copy
1234567891011121314
package 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

Main.java

copy
123456789101112131415
package 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

BrowserHistory.java

copy
1234567891011121314151617181920212223242526
import 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

BrowserHistory.java

copy
12345678910
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."); } }

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

BrowserHistory.java

copy
12345678910
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."); } }

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

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
package 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?

question mark

Qual é o princípio fundamental de uma estrutura de dados Stack?

Select the correct answer

question mark

Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?

Select the correct answer

question mark

Qual das seguintes coleções Java é considerada uma alternativa mais moderna ao Stack?

Select the correct answer

question mark

Em Java, o que o método pop() de uma Stack retorna?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 4

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Suggested prompts:

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?

bookEstrutura 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

Main.java

copy
12345678910111213141516
package 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

Main.java

copy
123456789101112
package 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

Main.java

copy
1234567891011121314
package 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

Main.java

copy
123456789101112131415
package 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

BrowserHistory.java

copy
1234567891011121314151617181920212223242526
import 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

BrowserHistory.java

copy
12345678910
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."); } }

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

BrowserHistory.java

copy
12345678910
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."); } }

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

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
package 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?

question mark

Qual é o princípio fundamental de uma estrutura de dados Stack?

Select the correct answer

question mark

Qual é o método utilizado para adicionar um elemento ao topo da pilha em Java?

Select the correct answer

question mark

Qual das seguintes coleções Java é considerada uma alternativa mais moderna ao Stack?

Select the correct answer

question mark

Em Java, o que o método pop() de uma Stack retorna?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 2. Capítulo 4
some-alt