Stack-Datenstruktur in Java
Swipe um das Menü anzuzeigen
Ein Stack ist eine Datenstruktur, die dem Last In, First Out (LIFO)-Prinzip folgt. Dasselbe Prinzip gilt für eine Deque, die zuvor behandelt wurde, und Java-Entwickler empfehlen die Verwendung einer Deque, wenn eine Datenstruktur nach dem LIFO-Prinzip arbeiten soll. Die Datenstruktur Stack ist veraltet und wird in der modernen Java-Entwicklung nicht empfohlen.
Einige Collections werden nicht mehr empfohlen und sind veraltet.
Veraltet
Wenn ein Element als veraltet markiert ist, bedeutet dies, dass die Autoren der Bibliothek oder Programmiersprache von der Verwendung in neuem Code abraten und empfehlen, neue Methoden, Klassen oder Ansätze zu verwenden, die möglicherweise sicherere, effizientere oder funktionalere Lösungen bieten.
Ein Beispiel ist die Klasse Vector in Java. Ihre Methoden wurden zugunsten modernerer Collections wie ArrayList und LinkedList als veraltet markiert. Wenn ein Programmierer dennoch Vector-Methoden verwendet, kann der Compiler eine Warnung ausgeben, dass diese Methoden veraltet sind.
Beispiel in 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)); } }
Daher wird nicht empfohlen, eine Datenstruktur wie Stack zu verwenden, dennoch wird sie in diesem Kapitel behandelt, da sie eine interessante Datenstruktur ist, die beispielsweise in Java Stack-Speicher verwendet wird.
Stack
Kompakt zusammengefasst, betrachten wir die Methoden der Stack-Klasse:
Methoden
push(E element): fügt ein Element oben auf den Stack hinzu.
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); } }
Das Hinzufügen erfolgt auf die gleiche Weise wie bei ArrayList, daher betrachten wir direkt diese Methode in Kombination mit der pop()-Methode:
pop(): entfernt und gibt das Element vom oberen Ende des Stapels zurück.
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); } }
Diese Methode entfernt ein Element vom oberen Ende des Stapels. Beachte, dass die pop()-Methode das zuletzt hinzugefügte Element aus dem Stapel entfernt. Genau so funktioniert das LIFO-Prinzip.
Es ist auch möglich, das Element am oberen Ende des Stapels anzusehen:
peek(): gibt das Element vom oberen Ende des Stapels zurück, ohne es zu entfernen.
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); } }
Mit dieser Methode betrachten wir das oberste Element im Stack.
Verwendung
Betrachten wir ein Beispiel für die Verwendung der Datenstruktur Stack zur Navigation zwischen Seiten in einem Browser (diese Vorwärts- und Zurück-Pfeile, die Sie häufig verwenden).
Planen wir die Implementierung des Browser-Verlaufs und implementieren Methoden für zwei Schaltflächen (goBack() und goForward()).
Falls Sie sich nicht sicher sind, auf welche Schaltflächen ich mich beziehe: Es handelt sich um diese Navigationsschaltflächen:
Implementierung einer Klasse mit Methoden zur Bedienung dieser beiden Schaltflächen unter Verwendung der Stack-Datenstruktur.
Funktionsweise
Verwendung von zwei Stacks und einer String-Variablen. Der erste Stack speichert die Links, die beim Klicken auf den "Zurück"-Pfeil aufgerufen werden. Der zweite Stack speichert die Links, die beim Klicken auf den "Vorwärts"-Pfeil aufgerufen werden. Zusätzlich gibt es eine String-Variable, die den aktuellen Seitenlink speichert.
In dieser Klasse existieren vier Methoden: visitPage(), goBack(), goForward() und getCurrentPage(). Schrittweise Erläuterung folgt.
Die Methode visitPage() leitet zur im Parameter angegebenen URL weiter. Beim Wechsel zu einer neuen Seite wird der alte Link zum backStack hinzugefügt. Der forwardStack wird geleert, sobald eine neue Seite aufgerufen wird.
Implementierung im Code:
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); } }
Auf diese Weise ist es möglich, zur vorherigen Seite zurückzukehren, wenn eine neue Seite aufgerufen wird.
Implementierung der Methode zum Zurückgehen. Funktionsweise: Der aktuelle Link wird zum forwardStack hinzugefügt, anschließend wird dieser Link aus dem backStack entfernt und der Variablen currentUrl zugewiesen.
Implementierung im Code:
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."); } }
Zur Erinnerung: Die Methode pop() entfernt das Element vom oberen Ende des Stacks und gibt es zurück. Daher wird mit dieser Methode der Wert der URL direkt der Variablen currentUrl zugewiesen.
Es wird außerdem geprüft, ob der backStack nicht leer ist; andernfalls ist ein Zurückkehren zum vorherigen Link nicht möglich (da dieser schlicht nicht existiert). Ist der Stack leer, wird eine entsprechende Meldung ausgegeben.
Nach demselben Prinzip wird die Methode zur Navigation zur Vorwärtsseite implementiert. Hierbei werden die Elemente im Stack einfach vertauscht:
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."); } }
Nun bleibt nur noch die Implementierung der Methode getCurrentPage(), die einfach den Wert von currentUrl zurückgibt.
Testen
Als Nächstes testen wir dies alles in der main-Methode. Die Methode visitPage() wird dreimal verwendet, um sicherzustellen, dass diese Links in der Historie gespeichert werden. Anschließend wird die Methode goBack() zweimal und danach die Methode goForward() einmal aufgerufen, um die Funktionalität der geschriebenen Methoden zu überprüfen.
Während dieses Prozesses verfolgen wir unseren Zustand mit der Methode getCurrentPage(). Der untenstehende Code kann ausgeführt werden; zudem können weitere Links eingefügt und verschiedene Methoden verwendet werden, um die Funktionalität dieser Klasse zu testen:
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; } }
Beachten Sie, dass die Klasse Stack veraltet ist und für die moderne Java-Entwicklung nicht empfohlen wird. Stattdessen sollte Deque verwendet werden, da dies eine effizientere Alternative darstellt. In diesem Beispiel wird Stack nach dem LIFO-Prinzip implementiert; Sie können jedoch auch Deque verwenden, da es sich um eine doppelt verkettete Warteschlange handelt, die sowohl das FIFO- als auch das LIFO-Prinzip unterstützt.
1. Was ist das grundlegende Prinzip einer Stack-Datenstruktur?
2. Welche Methode wird verwendet, um ein Element oben auf den Stack in Java hinzuzufügen?
3. Welche der folgenden Java-Collections gilt als moderne Alternative zu Stack?
4. Was gibt die Methode pop() eines Stack in Java zurück?
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen