Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Struttura Dati Stack in Java | Strutture Dati Avanzate in Java
Strutture Dati Java

bookStruttura Dati Stack in Java

Uno Stack è una struttura dati che segue il principio Last In, First Out (LIFO). Lo stesso principio si applica a un Deque, che hai già incontrato in precedenza, e gli sviluppatori Java raccomandano di utilizzare un Deque quando una struttura dati deve operare secondo il principio LIFO. La struttura dati Stack è obsoleta e non raccomandata nello sviluppo Java moderno.

Tuttavia, alcune collezioni non sono più raccomandate e sono state deprecate.

Deprecato

Quando un elemento viene contrassegnato come deprecato, significa che gli autori della libreria o del linguaggio di programmazione consigliano di evitarne l'uso nel nuovo codice e raccomandano di adottare nuovi metodi, classi o approcci che possano offrire soluzioni più sicure, efficienti o funzionali.

Un esempio è la classe Vector in Java. I suoi metodi sono stati deprecati a favore di collezioni più moderne come ArrayList e LinkedList. Se un programmatore utilizza ancora i metodi di Vector, il compilatore potrebbe emettere un avviso che questi metodi sono deprecati.

Esempio in 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)); } }

Pertanto, non è consigliato utilizzare una struttura dati come Stack, ma la discuteremo in questo capitolo perché è una struttura dati interessante utilizzata, ad esempio, nella memoria Stack di Java.

Stack

In sintesi, esaminiamo i metodi della classe Stack:

Metodi

push(E element): aggiunge un elemento in cima allo stack.

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); } }

L'aggiunta viene eseguita nello stesso modo di ArrayList, quindi analizziamo subito questo metodo in combinazione con il metodo pop():

pop(): rimuove e restituisce l'elemento dalla cima dello stack.

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); } }

Questo metodo rimuove un elemento dalla cima dello stack. Si noti che il metodo pop() rimuove l'ultimo elemento aggiunto allo stack. Questo è esattamente il funzionamento del principio LIFO.

È anche possibile visualizzare quale elemento si trova in cima allo stack:

peek(): restituisce l'elemento dalla cima dello stack senza rimuoverlo.

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); } }

Con questo metodo, si osserva l'elemento in cima allo stack.

Utilizzo

Consideriamo un esempio di utilizzo della struttura dati Stack per la navigazione tra le pagine in un browser (quelle frecce avanti e indietro che si usano frequentemente).

Pianifichiamo l'implementazione della cronologia del browser e implementiamo i metodi per due pulsanti (goBack() e goForward()). Se non è chiaro a quali pulsanti ci si riferisce, si tratta di questi pulsanti di navigazione:

Implementazione di una classe con metodi per gestire questi due pulsanti utilizzando la struttura dati Stack.

Funzionamento

Saranno presenti due stack e una variabile String. Il primo stack memorizza i link visitati tramite il clic sulla freccia "indietro". Il secondo stack memorizza i link visitati tramite il clic sulla freccia "avanti". Una variabile String memorizza il link della pagina corrente.

In questa classe saranno presenti quattro metodi: visitPage(), goBack(), goForward() e getCurrentPage(). Analisi dettagliata di ciascun metodo.

Il metodo visitPage() reindirizza all'URL specificato come parametro. Quando si passa a una nuova pagina, il vecchio link viene aggiunto al backStack. Il forwardStack viene svuotato durante la navigazione verso una nuova pagina.

Di seguito l'implementazione nel codice:

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); } }

In questo modo è possibile tornare alla pagina precedente durante la navigazione verso una nuova pagina.

Implementazione del metodo per tornare indietro. Funzionamento: si aggiunge il link corrente al forwardStack, quindi si rimuove questo link dal backStack e lo si assegna a currentUrl.

Di seguito l'implementazione nel codice:

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

Ricorda che il metodo pop() rimuove l'elemento dalla cima dello stack e lo restituisce. Pertanto, utilizzando questo metodo, assegniamo immediatamente il valore dell'URL alla variabile currentUrl.

Verifichiamo inoltre che backStack non sia vuoto; altrimenti, non sarà possibile tornare al link precedente (semplicemente perché non esisterà). Se lo stack è vuoto, viene visualizzato un messaggio corrispondente.

Allo stesso modo, implementiamo il metodo per la navigazione alla pagina successiva. Semplicemente scambiamo gli elementi nello stack:

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

Ora, tutto ciò che resta è implementare il metodo getCurrentPage(), che restituirà semplicemente il valore di currentUrl.

Verifica

Successivamente, si procede alla verifica di tutto questo nel metodo main. Il metodo visitPage() verrà utilizzato tre volte per assicurarsi che questi collegamenti vengano salvati nella cronologia. Poi, il metodo goBack() verrà utilizzato due volte, seguito dal metodo goForward() una volta, per verificare la funzionalità dei metodi scritti.

Durante questo processo, lo stato verrà monitorato utilizzando il metodo getCurrentPage(). È possibile eseguire il codice sottostante e anche provare a inserire altri collegamenti e utilizzare diversi metodi per testare la funzionalità di questa 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; } }

Ricorda che la classe Stack è obsoleta e non consigliata per l'uso nello sviluppo moderno in Java. È preferibile utilizzare Deque, che rappresenta un'alternativa più efficiente. In questo esempio, Stack viene implementata secondo il principio LIFO, ma è possibile implementare anche Deque, in quanto si tratta di una coda a doppia estremità che supporta sia i principi FIFO che LIFO.

1. Qual è il principio fondamentale di una struttura dati Stack?

2. Qual è il metodo utilizzato per aggiungere un elemento in cima allo stack in Java?

3. Quale delle seguenti collezioni Java è considerata un'alternativa più moderna a Stack?

4. In Java, cosa restituirà il metodo pop() di uno Stack?

question mark

Qual è il principio fondamentale di una struttura dati Stack?

Select the correct answer

question mark

Qual è il metodo utilizzato per aggiungere un elemento in cima allo stack in Java?

Select the correct answer

question mark

Quale delle seguenti collezioni Java è considerata un'alternativa più moderna a Stack?

Select the correct answer

question mark

In Java, cosa restituirà il metodo pop() di uno Stack?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 2. Capitolo 4

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

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?

bookStruttura Dati Stack in Java

Scorri per mostrare il menu

Uno Stack è una struttura dati che segue il principio Last In, First Out (LIFO). Lo stesso principio si applica a un Deque, che hai già incontrato in precedenza, e gli sviluppatori Java raccomandano di utilizzare un Deque quando una struttura dati deve operare secondo il principio LIFO. La struttura dati Stack è obsoleta e non raccomandata nello sviluppo Java moderno.

Tuttavia, alcune collezioni non sono più raccomandate e sono state deprecate.

Deprecato

Quando un elemento viene contrassegnato come deprecato, significa che gli autori della libreria o del linguaggio di programmazione consigliano di evitarne l'uso nel nuovo codice e raccomandano di adottare nuovi metodi, classi o approcci che possano offrire soluzioni più sicure, efficienti o funzionali.

Un esempio è la classe Vector in Java. I suoi metodi sono stati deprecati a favore di collezioni più moderne come ArrayList e LinkedList. Se un programmatore utilizza ancora i metodi di Vector, il compilatore potrebbe emettere un avviso che questi metodi sono deprecati.

Esempio in 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)); } }

Pertanto, non è consigliato utilizzare una struttura dati come Stack, ma la discuteremo in questo capitolo perché è una struttura dati interessante utilizzata, ad esempio, nella memoria Stack di Java.

Stack

In sintesi, esaminiamo i metodi della classe Stack:

Metodi

push(E element): aggiunge un elemento in cima allo stack.

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); } }

L'aggiunta viene eseguita nello stesso modo di ArrayList, quindi analizziamo subito questo metodo in combinazione con il metodo pop():

pop(): rimuove e restituisce l'elemento dalla cima dello stack.

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); } }

Questo metodo rimuove un elemento dalla cima dello stack. Si noti che il metodo pop() rimuove l'ultimo elemento aggiunto allo stack. Questo è esattamente il funzionamento del principio LIFO.

È anche possibile visualizzare quale elemento si trova in cima allo stack:

peek(): restituisce l'elemento dalla cima dello stack senza rimuoverlo.

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); } }

Con questo metodo, si osserva l'elemento in cima allo stack.

Utilizzo

Consideriamo un esempio di utilizzo della struttura dati Stack per la navigazione tra le pagine in un browser (quelle frecce avanti e indietro che si usano frequentemente).

Pianifichiamo l'implementazione della cronologia del browser e implementiamo i metodi per due pulsanti (goBack() e goForward()). Se non è chiaro a quali pulsanti ci si riferisce, si tratta di questi pulsanti di navigazione:

Implementazione di una classe con metodi per gestire questi due pulsanti utilizzando la struttura dati Stack.

Funzionamento

Saranno presenti due stack e una variabile String. Il primo stack memorizza i link visitati tramite il clic sulla freccia "indietro". Il secondo stack memorizza i link visitati tramite il clic sulla freccia "avanti". Una variabile String memorizza il link della pagina corrente.

In questa classe saranno presenti quattro metodi: visitPage(), goBack(), goForward() e getCurrentPage(). Analisi dettagliata di ciascun metodo.

Il metodo visitPage() reindirizza all'URL specificato come parametro. Quando si passa a una nuova pagina, il vecchio link viene aggiunto al backStack. Il forwardStack viene svuotato durante la navigazione verso una nuova pagina.

Di seguito l'implementazione nel codice:

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); } }

In questo modo è possibile tornare alla pagina precedente durante la navigazione verso una nuova pagina.

Implementazione del metodo per tornare indietro. Funzionamento: si aggiunge il link corrente al forwardStack, quindi si rimuove questo link dal backStack e lo si assegna a currentUrl.

Di seguito l'implementazione nel codice:

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

Ricorda che il metodo pop() rimuove l'elemento dalla cima dello stack e lo restituisce. Pertanto, utilizzando questo metodo, assegniamo immediatamente il valore dell'URL alla variabile currentUrl.

Verifichiamo inoltre che backStack non sia vuoto; altrimenti, non sarà possibile tornare al link precedente (semplicemente perché non esisterà). Se lo stack è vuoto, viene visualizzato un messaggio corrispondente.

Allo stesso modo, implementiamo il metodo per la navigazione alla pagina successiva. Semplicemente scambiamo gli elementi nello stack:

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

Ora, tutto ciò che resta è implementare il metodo getCurrentPage(), che restituirà semplicemente il valore di currentUrl.

Verifica

Successivamente, si procede alla verifica di tutto questo nel metodo main. Il metodo visitPage() verrà utilizzato tre volte per assicurarsi che questi collegamenti vengano salvati nella cronologia. Poi, il metodo goBack() verrà utilizzato due volte, seguito dal metodo goForward() una volta, per verificare la funzionalità dei metodi scritti.

Durante questo processo, lo stato verrà monitorato utilizzando il metodo getCurrentPage(). È possibile eseguire il codice sottostante e anche provare a inserire altri collegamenti e utilizzare diversi metodi per testare la funzionalità di questa 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; } }

Ricorda che la classe Stack è obsoleta e non consigliata per l'uso nello sviluppo moderno in Java. È preferibile utilizzare Deque, che rappresenta un'alternativa più efficiente. In questo esempio, Stack viene implementata secondo il principio LIFO, ma è possibile implementare anche Deque, in quanto si tratta di una coda a doppia estremità che supporta sia i principi FIFO che LIFO.

1. Qual è il principio fondamentale di una struttura dati Stack?

2. Qual è il metodo utilizzato per aggiungere un elemento in cima allo stack in Java?

3. Quale delle seguenti collezioni Java è considerata un'alternativa più moderna a Stack?

4. In Java, cosa restituirà il metodo pop() di uno Stack?

question mark

Qual è il principio fondamentale di una struttura dati Stack?

Select the correct answer

question mark

Qual è il metodo utilizzato per aggiungere un elemento in cima allo stack in Java?

Select the correct answer

question mark

Quale delle seguenti collezioni Java è considerata un'alternativa più moderna a Stack?

Select the correct answer

question mark

In Java, cosa restituirà il metodo pop() di uno Stack?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 2. Capitolo 4
some-alt