Stak-datastruktur i Java
En Stack er en datastruktur, der følger Last In, First Out (LIFO)-princippet. Det samme princip gælder for en Deque, som du tidligere har lært om, og Java-udviklere anbefaler at bruge en Deque, når en datastruktur skal fungere efter LIFO-princippet. Stack-datastrukturen er forældet og anbefales ikke i moderne Java-udvikling.
Dog er nogle collections ikke længere anbefalet og er blevet udfaset.
Udfaset
Når et element er markeret som udfaset, betyder det, at forfatterne af biblioteket eller programmeringssproget fraråder brugen i ny kode og anbefaler at tage nye metoder, klasser eller tilgange i brug, som kan give mere sikre, mere effektive eller mere funktionelle løsninger.
Et eksempel er Vector-klassen i Java. Dens metoder er blevet udfaset til fordel for mere moderne samlinger som ArrayList og LinkedList. Hvis en programmør stadig anvender Vector-metoder, kan compileren give en advarsel om, at disse metoder er forældede.
Eksempel i 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)); } }
Derfor er det ikke anbefalet at anvende en datastruktur som Stack, men vi vil gennemgå den i dette kapitel, da det er en interessant datastruktur, der for eksempel bruges i Java Stack-hukommelse.
Stack
Kort og præcist, her er metoderne i Stack-klassen:
Metoder
push(E element): tilføjer et element øverst i stacken.
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); } }
Tilføjelse udføres på samme måde som i ArrayList, så lad os straks se på denne metode i kombination med pop()-metoden:
pop(): fjerner og returnerer elementet fra toppen af stakken.
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); } }
Denne metode fjerner ét element fra toppen af stakken. Bemærk, at pop()-metoden fjerner det sidst tilføjede element fra stakken. Det er præcis sådan, LIFO-princippet fungerer.
Du kan også se, hvilket element der er øverst i stakken:
peek(): returnerer elementet fra toppen af stakken uden at fjerne det.
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); } }
Med denne metode kigger vi på det øverste element i stakken.
Anvendelse
Lad os overveje et eksempel på brug af datastrukturen Stack til at navigere mellem sider i en browser (de fremad og tilbage pile, som du ofte bruger).
Lad os planlægge implementeringen af browserhistorikken og implementere metoder til to knapper (goBack() og goForward()).
Hvis du ikke er sikker på, hvilke knapper jeg henviser til, taler jeg om disse navigationsknapper:
Lad os implementere en klasse, der har metoder til at betjene disse to knapper ved hjælp af datastrukturen Stack.
Sådan fungerer det
Du vil have to stacks og en String-variabel. Den første stack vil gemme de links, vi navigerer til ved at klikke på "tilbage"-pilen. Den anden stack vil gemme de links, du navigerer til ved at klikke på "frem"-pilen. Du vil også have en String-variabel, der gemmer det aktuelle siders link.
I denne klasse vil der være fire metoder: visitPage(), goBack(), goForward() og getCurrentPage(). Lad os gennemgå dem trin for trin.
Metoden visitPage() vil omdirigere os til URL'en angivet i parameteren. Når du går til en ny side, vil det gamle link blive tilføjet til backStack. forwardStack vil blive tømt, når du går til en ny side.
Lad os se implementeringen i koden:
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); } }
På denne måde kan vi vende tilbage til den forrige side, når vi navigerer til en ny side.
Lad os implementere metoden til at gå tilbage. Den vil fungere sådan: vi tilføjer det aktuelle link til forwardStack, derefter fjerner vi dette link fra backStack og tildeler det til currentUrl.
Lad os se implementeringen i koden:
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."); } }
Jeg vil minde dig om, at metoden pop() fjerner elementet fra toppen af stakken og returnerer det. Derfor tildeles URL'ens værdi straks til variablen currentUrl ved brug af denne metode.
Vi kontrollerer også, at backStack ikke er tom; ellers vil det ikke være muligt at gå tilbage til det forrige link (simpelthen fordi det ikke findes). Hvis stakken er tom, vises en tilsvarende besked.
På samme måde implementeres metoden til at navigere til fremad-siden. Vi bytter blot elementerne i stakken:
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."); } }
Nu mangler kun implementeringen af metoden getCurrentPage(), som blot returnerer værdien af currentUrl.
Test
Dernæst testes dette i main-metoden. Metoden visitPage() anvendes tre gange for at sikre, at disse links gemmes i historikken. Herefter anvendes goBack() to gange, efterfulgt af goForward() én gang, for at verificere funktionaliteten af de implementerede metoder.
Under denne proces overvåges tilstanden ved hjælp af metoden getCurrentPage(). Koden nedenfor kan afvikles, og det er også muligt at indsætte flere links og anvende forskellige metoder for at teste denne klasses funktionalitet:
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; } }
Bemærk, at klassen Stack er forældet og ikke anbefales til moderne Java-udvikling. Det er i stedet bedre at anvende Deque, som er et mere effektivt alternativ. I dette eksempel er Stack implementeret ud fra LIFO-princippet, og det er også muligt at implementere Deque, da det er en dobbelt-endt kø, der understøtter både FIFO- og LIFO-principper.
1. Hvad er det primære princip for en Stack datastruktur?
2. Hvilken metode bruges til at tilføje et element øverst i stakken i Java?
3. Hvilken af følgende Java-samlinger betragtes som et mere moderne alternativ til Stack?
4. Hvad vil pop()-metoden for en Stack returnere i Java?
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Fantastisk!
Completion rate forbedret til 4
Stak-datastruktur i Java
Stryg for at vise menuen
En Stack er en datastruktur, der følger Last In, First Out (LIFO)-princippet. Det samme princip gælder for en Deque, som du tidligere har lært om, og Java-udviklere anbefaler at bruge en Deque, når en datastruktur skal fungere efter LIFO-princippet. Stack-datastrukturen er forældet og anbefales ikke i moderne Java-udvikling.
Dog er nogle collections ikke længere anbefalet og er blevet udfaset.
Udfaset
Når et element er markeret som udfaset, betyder det, at forfatterne af biblioteket eller programmeringssproget fraråder brugen i ny kode og anbefaler at tage nye metoder, klasser eller tilgange i brug, som kan give mere sikre, mere effektive eller mere funktionelle løsninger.
Et eksempel er Vector-klassen i Java. Dens metoder er blevet udfaset til fordel for mere moderne samlinger som ArrayList og LinkedList. Hvis en programmør stadig anvender Vector-metoder, kan compileren give en advarsel om, at disse metoder er forældede.
Eksempel i 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)); } }
Derfor er det ikke anbefalet at anvende en datastruktur som Stack, men vi vil gennemgå den i dette kapitel, da det er en interessant datastruktur, der for eksempel bruges i Java Stack-hukommelse.
Stack
Kort og præcist, her er metoderne i Stack-klassen:
Metoder
push(E element): tilføjer et element øverst i stacken.
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); } }
Tilføjelse udføres på samme måde som i ArrayList, så lad os straks se på denne metode i kombination med pop()-metoden:
pop(): fjerner og returnerer elementet fra toppen af stakken.
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); } }
Denne metode fjerner ét element fra toppen af stakken. Bemærk, at pop()-metoden fjerner det sidst tilføjede element fra stakken. Det er præcis sådan, LIFO-princippet fungerer.
Du kan også se, hvilket element der er øverst i stakken:
peek(): returnerer elementet fra toppen af stakken uden at fjerne det.
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); } }
Med denne metode kigger vi på det øverste element i stakken.
Anvendelse
Lad os overveje et eksempel på brug af datastrukturen Stack til at navigere mellem sider i en browser (de fremad og tilbage pile, som du ofte bruger).
Lad os planlægge implementeringen af browserhistorikken og implementere metoder til to knapper (goBack() og goForward()).
Hvis du ikke er sikker på, hvilke knapper jeg henviser til, taler jeg om disse navigationsknapper:
Lad os implementere en klasse, der har metoder til at betjene disse to knapper ved hjælp af datastrukturen Stack.
Sådan fungerer det
Du vil have to stacks og en String-variabel. Den første stack vil gemme de links, vi navigerer til ved at klikke på "tilbage"-pilen. Den anden stack vil gemme de links, du navigerer til ved at klikke på "frem"-pilen. Du vil også have en String-variabel, der gemmer det aktuelle siders link.
I denne klasse vil der være fire metoder: visitPage(), goBack(), goForward() og getCurrentPage(). Lad os gennemgå dem trin for trin.
Metoden visitPage() vil omdirigere os til URL'en angivet i parameteren. Når du går til en ny side, vil det gamle link blive tilføjet til backStack. forwardStack vil blive tømt, når du går til en ny side.
Lad os se implementeringen i koden:
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); } }
På denne måde kan vi vende tilbage til den forrige side, når vi navigerer til en ny side.
Lad os implementere metoden til at gå tilbage. Den vil fungere sådan: vi tilføjer det aktuelle link til forwardStack, derefter fjerner vi dette link fra backStack og tildeler det til currentUrl.
Lad os se implementeringen i koden:
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."); } }
Jeg vil minde dig om, at metoden pop() fjerner elementet fra toppen af stakken og returnerer det. Derfor tildeles URL'ens værdi straks til variablen currentUrl ved brug af denne metode.
Vi kontrollerer også, at backStack ikke er tom; ellers vil det ikke være muligt at gå tilbage til det forrige link (simpelthen fordi det ikke findes). Hvis stakken er tom, vises en tilsvarende besked.
På samme måde implementeres metoden til at navigere til fremad-siden. Vi bytter blot elementerne i stakken:
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."); } }
Nu mangler kun implementeringen af metoden getCurrentPage(), som blot returnerer værdien af currentUrl.
Test
Dernæst testes dette i main-metoden. Metoden visitPage() anvendes tre gange for at sikre, at disse links gemmes i historikken. Herefter anvendes goBack() to gange, efterfulgt af goForward() én gang, for at verificere funktionaliteten af de implementerede metoder.
Under denne proces overvåges tilstanden ved hjælp af metoden getCurrentPage(). Koden nedenfor kan afvikles, og det er også muligt at indsætte flere links og anvende forskellige metoder for at teste denne klasses funktionalitet:
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; } }
Bemærk, at klassen Stack er forældet og ikke anbefales til moderne Java-udvikling. Det er i stedet bedre at anvende Deque, som er et mere effektivt alternativ. I dette eksempel er Stack implementeret ud fra LIFO-princippet, og det er også muligt at implementere Deque, da det er en dobbelt-endt kø, der understøtter både FIFO- og LIFO-principper.
1. Hvad er det primære princip for en Stack datastruktur?
2. Hvilken metode bruges til at tilføje et element øverst i stakken i Java?
3. Hvilken af følgende Java-samlinger betragtes som et mere moderne alternativ til Stack?
4. Hvad vil pop()-metoden for en Stack returnere i Java?
Tak for dine kommentarer!