Stackdatastruktur i Java
En Stack är en datastruktur som följer principen Last In, First Out (LIFO). Samma princip gäller för en Deque, som du lärde dig om tidigare, och Java-utvecklare rekommenderar att använda en Deque när en datastruktur behöver arbeta enligt LIFO-principen. Datastrukturen Stack är föråldrad och rekommenderas inte i modern Java-utveckling.
Vissa samlingar är dock inte längre rekommenderade och har blivit föråldrade.
Föråldrad
När ett element är markerat som föråldrat innebär det att författarna till biblioteket eller programmeringsspråket avråder från att använda det i ny kod och rekommenderar att använda nya metoder, klasser eller tillvägagångssätt som kan erbjuda säkrare, mer effektiva eller mer funktionella lösningar.
Ett exempel är klassen Vector i Java. Dess metoder har blivit föråldrade till förmån för modernare samlingar som ArrayList och LinkedList. Om en programmerare fortfarande använder Vector-metoder kan kompilatorn utfärda en varning om att dessa metoder är föråldrade.
Exempel 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)); } }
Det är därför inte rekommenderat att använda en datastruktur som Stack, men vi kommer att diskutera den i detta kapitel eftersom det är en intressant datastruktur som används, till exempel, i Java Stack-minne.
Stack
Rakt på sak, låt oss titta på metoderna i klassen Stack:
Metoder
push(E element): lägger till ett 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); } }
Tillägg sker på samma sätt som i ArrayList, så låt oss direkt titta på denna metod i kombination med pop()-metoden:
pop(): tar bort och returnerar elementet från toppen av stacken.
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); } }
Denna metod tar bort ett element från toppen av stacken. Observera att pop()-metoden tar bort det senast tillagda elementet från stacken. Det är precis så LIFO-principen fungerar.
Du kan också se vilket element som ligger överst i stacken:
peek(): returnerar elementet från toppen av stacken utan att ta bort 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 denna metod tittar vi på det översta elementet i stacken.
Användning
Låt oss titta på ett exempel på hur datastrukturen Stack används för att navigera mellan sidor i en webbläsare (de där framåt och bakåt pilarna som du ofta använder).
Låt oss planera implementeringen av webbläsarhistorik och implementera metoder för två knappar (goBack() och goForward()).
Om du är osäker på vilka knappar jag syftar på, menar jag dessa navigeringsknappar:
Låt oss implementera en klass som har metoder för att hantera dessa två knappar med hjälp av datastrukturen Stack.
Hur det kommer att fungera
Du kommer att ha två stackar och en String-variabel. Den första stacken kommer att lagra länkarna vi navigerar till genom att klicka på "bakåt"-pilen. Den andra stacken kommer att lagra länkarna du navigerar till genom att klicka på "framåt"-pilen. Du kommer också att ha en String-variabel som lagrar den aktuella sidans länk.
I denna klass kommer det att finnas fyra metoder: visitPage(), goBack(), goForward() och getCurrentPage(). Låt oss gå igenom dem steg för steg.
Metoden visitPage() kommer att omdirigera oss till URL:en som anges i parametern. När du går till en ny sida kommer den gamla länken att läggas till i backStack. forwardStack kommer att rensas när du går till en ny sida.
Låt oss titta på implementationen 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å detta sätt kan vi återvända till föregående sida när vi navigerar till en ny sida.
Låt oss implementera metoden för att gå bakåt. Den kommer att fungera så här: vi lägger till den aktuella länken i forwardStack, sedan tar vi bort denna länk från backStack och tilldelar den till currentUrl.
Låt oss titta på implementationen 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."); } }
Observera att metoden pop() tar bort elementet från toppen av stacken och returnerar det. Därför tilldelas värdet av URL:en direkt till variabeln currentUrl med denna metod.
Vi kontrollerar också att backStack inte är tom; annars är det inte möjligt att gå tillbaka till föregående länk (eftersom den helt enkelt inte finns där). Om stacken är tom, visas ett motsvarande meddelande.
På samma sätt implementeras metoden för att navigera till framåt-sidan. Vi byter helt enkelt plats på elementen i stacken:
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 återstår endast att implementera metoden getCurrentPage(), som helt enkelt returnerar värdet av currentUrl.
Testning
Därefter testas allt detta i metoden main. Metoden visitPage() används tre gånger för att säkerställa att dessa länkar sparas i historiken. Därefter används metoden goBack() två gånger, följt av metoden goForward() en gång, för att verifiera funktionaliteten hos de skrivna metoderna.
Under denna process spåras tillståndet med hjälp av metoden getCurrentPage(). Koden nedan kan köras och det går även att prova att lägga till fler länkar och använda olika metoder för att testa funktionaliteten i denna klass:
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; } }
Observera att klassen Stack är föråldrad och inte rekommenderas för användning i modern Java-utveckling. Det är istället bättre att använda Deque, som är ett mer effektivt alternativ. I detta exempel implementeras Stack enligt LIFO-principen, och det går även att implementera Deque, eftersom det är en dubbelsidig kö som stödjer både FIFO- och LIFO-principerna.
1. Vad är den grundläggande principen för en Stack-datastruktur?
2. Vilken metod används för att lägga till ett element överst i stacken i Java?
3. Vilken av följande Java-samlingar anses vara ett mer modernt alternativ till Stack?
4. Vad returnerar metoden pop() för en Stack i Java?
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
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?
Fantastiskt!
Completion betyg förbättrat till 4
Stackdatastruktur i Java
Svep för att visa menyn
En Stack är en datastruktur som följer principen Last In, First Out (LIFO). Samma princip gäller för en Deque, som du lärde dig om tidigare, och Java-utvecklare rekommenderar att använda en Deque när en datastruktur behöver arbeta enligt LIFO-principen. Datastrukturen Stack är föråldrad och rekommenderas inte i modern Java-utveckling.
Vissa samlingar är dock inte längre rekommenderade och har blivit föråldrade.
Föråldrad
När ett element är markerat som föråldrat innebär det att författarna till biblioteket eller programmeringsspråket avråder från att använda det i ny kod och rekommenderar att använda nya metoder, klasser eller tillvägagångssätt som kan erbjuda säkrare, mer effektiva eller mer funktionella lösningar.
Ett exempel är klassen Vector i Java. Dess metoder har blivit föråldrade till förmån för modernare samlingar som ArrayList och LinkedList. Om en programmerare fortfarande använder Vector-metoder kan kompilatorn utfärda en varning om att dessa metoder är föråldrade.
Exempel 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)); } }
Det är därför inte rekommenderat att använda en datastruktur som Stack, men vi kommer att diskutera den i detta kapitel eftersom det är en intressant datastruktur som används, till exempel, i Java Stack-minne.
Stack
Rakt på sak, låt oss titta på metoderna i klassen Stack:
Metoder
push(E element): lägger till ett 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); } }
Tillägg sker på samma sätt som i ArrayList, så låt oss direkt titta på denna metod i kombination med pop()-metoden:
pop(): tar bort och returnerar elementet från toppen av stacken.
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); } }
Denna metod tar bort ett element från toppen av stacken. Observera att pop()-metoden tar bort det senast tillagda elementet från stacken. Det är precis så LIFO-principen fungerar.
Du kan också se vilket element som ligger överst i stacken:
peek(): returnerar elementet från toppen av stacken utan att ta bort 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 denna metod tittar vi på det översta elementet i stacken.
Användning
Låt oss titta på ett exempel på hur datastrukturen Stack används för att navigera mellan sidor i en webbläsare (de där framåt och bakåt pilarna som du ofta använder).
Låt oss planera implementeringen av webbläsarhistorik och implementera metoder för två knappar (goBack() och goForward()).
Om du är osäker på vilka knappar jag syftar på, menar jag dessa navigeringsknappar:
Låt oss implementera en klass som har metoder för att hantera dessa två knappar med hjälp av datastrukturen Stack.
Hur det kommer att fungera
Du kommer att ha två stackar och en String-variabel. Den första stacken kommer att lagra länkarna vi navigerar till genom att klicka på "bakåt"-pilen. Den andra stacken kommer att lagra länkarna du navigerar till genom att klicka på "framåt"-pilen. Du kommer också att ha en String-variabel som lagrar den aktuella sidans länk.
I denna klass kommer det att finnas fyra metoder: visitPage(), goBack(), goForward() och getCurrentPage(). Låt oss gå igenom dem steg för steg.
Metoden visitPage() kommer att omdirigera oss till URL:en som anges i parametern. När du går till en ny sida kommer den gamla länken att läggas till i backStack. forwardStack kommer att rensas när du går till en ny sida.
Låt oss titta på implementationen 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å detta sätt kan vi återvända till föregående sida när vi navigerar till en ny sida.
Låt oss implementera metoden för att gå bakåt. Den kommer att fungera så här: vi lägger till den aktuella länken i forwardStack, sedan tar vi bort denna länk från backStack och tilldelar den till currentUrl.
Låt oss titta på implementationen 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."); } }
Observera att metoden pop() tar bort elementet från toppen av stacken och returnerar det. Därför tilldelas värdet av URL:en direkt till variabeln currentUrl med denna metod.
Vi kontrollerar också att backStack inte är tom; annars är det inte möjligt att gå tillbaka till föregående länk (eftersom den helt enkelt inte finns där). Om stacken är tom, visas ett motsvarande meddelande.
På samma sätt implementeras metoden för att navigera till framåt-sidan. Vi byter helt enkelt plats på elementen i stacken:
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 återstår endast att implementera metoden getCurrentPage(), som helt enkelt returnerar värdet av currentUrl.
Testning
Därefter testas allt detta i metoden main. Metoden visitPage() används tre gånger för att säkerställa att dessa länkar sparas i historiken. Därefter används metoden goBack() två gånger, följt av metoden goForward() en gång, för att verifiera funktionaliteten hos de skrivna metoderna.
Under denna process spåras tillståndet med hjälp av metoden getCurrentPage(). Koden nedan kan köras och det går även att prova att lägga till fler länkar och använda olika metoder för att testa funktionaliteten i denna klass:
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; } }
Observera att klassen Stack är föråldrad och inte rekommenderas för användning i modern Java-utveckling. Det är istället bättre att använda Deque, som är ett mer effektivt alternativ. I detta exempel implementeras Stack enligt LIFO-principen, och det går även att implementera Deque, eftersom det är en dubbelsidig kö som stödjer både FIFO- och LIFO-principerna.
1. Vad är den grundläggande principen för en Stack-datastruktur?
2. Vilken metod används för att lägga till ett element överst i stacken i Java?
3. Vilken av följande Java-samlingar anses vara ett mer modernt alternativ till Stack?
4. Vad returnerar metoden pop() för en Stack i Java?
Tack för dina kommentarer!