Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Pino-Tietorakenne Javassa | Edistyneet Tietorakenteet Javassa
Practice
Projects
Quizzes & Challenges
Quizzes
Challenges
/
Java-tietorakenteet

bookPino-Tietorakenne Javassa

Stack on tietorakenne, joka noudattaa viimeksi sisään, ensimmäisenä ulos (LIFO) -periaatetta. Sama periaate koskee myös Deque-tietorakennetta, johon tutustuit aiemmin, ja Java-kehittäjät suosittelevat käyttämään Deque-rakennetta, kun tietorakenteen tulee toimia LIFO-periaatteella. Stack-tietorakenne on vanhentunut eikä sitä suositella käytettäväksi nykyaikaisessa Java-kehityksessä.

Jotkin kokoelmat eivät enää ole suositeltavia ja ne on merkitty vanhentuneiksi.

Vanhentunut

Kun elementti on merkitty vanhentuneeksi, se tarkoittaa, että kirjaston tai ohjelmointikielen tekijät neuvovat välttämään sen käyttöä uudessa koodissa ja suosittelevat uusien menetelmien, luokkien tai lähestymistapojen käyttöönottoa, jotka voivat tarjota turvallisempia, tehokkaampia tai toiminnallisempia ratkaisuja.

Esimerkkinä on Vector-luokka Javassa. Sen metodit on merkitty vanhentuneiksi nykyaikaisempien kokoelmien, kuten ArrayList ja LinkedList, hyväksi. Jos ohjelmoija käyttää edelleen Vector-metodeja, kääntäjä voi antaa varoituksen siitä, että nämä metodit ovat vanhentuneita.

Esimerkki Javassa:

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

Tästä syystä ei suositella käyttämään tietorakennetta kuten Stack, mutta käsittelemme sitä tässä luvussa, koska se on mielenkiintoinen tietorakenne, jota käytetään esimerkiksi Javassa Stack-muisti.

Pino

Ytimekkäästi, tarkastellaan Stack-luokan metodeja:

Metodit

push(E element): lisää alkion pinon päälle.

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

Lisäys tapahtuu samalla tavalla kuin ArrayList:ssä, joten tarkastellaan tätä menetelmää yhdessä pop()-menetelmän kanssa:

pop(): poistaa ja palauttaa alkion pinon päältä.

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

Tämä menetelmä poistaa yhden alkion pinon päältä. Huomaa, että pop()-menetelmä poistaa viimeksi lisätyn alkion pinosta. Tämä on juuri se, miten LIFO-periaate toimii.

Voit myös tarkistaa, mikä alkio on pinon päällä:

peek(): palauttaa alkion pinon päältä ilman että sitä poistetaan.

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

Tällä menetelmällä tarkastellaan pinon päällimmäistä alkiota.

Käyttö

Tarkastellaan esimerkkiä Stack-tietorakenteen käytöstä selaimen sivuhistorian hallinnassa (ne eteenpäin ja taaksepäin nuolet, joita käytät usein).

Suunnitellaan selaimen historian toteutus ja toteutetaan kaksi painiketta vastaavat metodit (goBack() ja goForward()). Jos et ole varma, mistä painikkeista on kyse, tarkoitan näitä navigointipainikkeita:

Toteutetaan luokka, jossa on menetelmät näiden kahden painikkeen käyttämiseen hyödyntäen Stack-tietorakennetta.

Toimintaperiaate

Käytössäsi on kaksi pinoa ja String-muuttuja. Ensimmäinen pino tallentaa linkit, joita selaat napsauttamalla "takaisin"-nuolta. Toinen pino tallentaa linkit, joita selaat napsauttamalla "eteenpäin"-nuolta. Lisäksi käytössäsi on String-muuttuja, joka tallentaa nykyisen sivun linkin.

Tässä luokassa on neljä menetelmää: visitPage(), goBack(), goForward() ja getCurrentPage(). Käydään ne läpi vaiheittain.

visitPage()-menetelmä ohjaa meidät parametrina annettuun URL-osoitteeseen. Kun siirrytään uudelle sivulle, vanha linkki lisätään backStack-pinoon. forwardStack tyhjennetään, kun siirrytään uudelle sivulle.

Tarkastellaan toteutusta koodissa:

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

Näin voimme palata edelliselle sivulle, kun siirrytään uudelle sivulle.

Toteutetaan takaisin siirtymisen menetelmä. Se toimii seuraavasti: lisätään nykyinen linkki forwardStack-pinoon, sitten poistetaan tämä linkki backStack-pinosta ja asetetaan se currentUrl-muuttujaan.

Tarkastellaan toteutusta koodissa:

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

Muistutuksena, pop()-metodi poistaa alkion pinon päältä ja palauttaa sen. Tämän vuoksi tällä metodilla voimme suoraan asettaa URL-osoitteen arvon muuttujaan currentUrl.

Tarkistamme myös, että backStack ei ole tyhjä; muuten emme voi palata edelliseen linkkiin (koska sitä ei ole olemassa). Jos pino on tyhjä, tulostamme vastaavan viestin.

Samalla tavalla toteutamme metodin siirtymiselle seuraavalle sivulle. Vaihdamme yksinkertaisesti pinon alkioiden järjestystä:

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

Nyt jäljellä on vain getCurrentPage()-metodin toteutus, joka yksinkertaisesti palauttaa currentUrl-arvon.

Testaus

Seuraavaksi testataan tätä kaikkea main-metodissa. Käytetään visitPage()-metodia kolme kertaa varmistaaksemme, että nämä linkit tallentuvat historiaan. Sen jälkeen käytetään goBack()-metodia kahdesti ja lopuksi goForward()-metodia kerran varmistaaksemme metodien toimivuuden.

Tämän prosessin aikana seurataan tilaa getCurrentPage()-metodilla. Voit suorittaa alla olevan koodin ja myös kokeilla lisätä lisää linkkejä sekä käyttää eri metodeja testataksesi tämän luokan toiminnallisuutta:

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

Muista, että Stack-luokka on vanhentunut eikä sitä suositella käytettäväksi nykyaikaisessa Java-kehityksessä. Sen sijaan on parempi käyttää Deque-rakennetta, joka on tehokkaampi vaihtoehto. Tässä esimerkissä Stack on toteutettu LIFO-periaatteella, ja voit myös toteuttaa Deque-rakenteen, sillä se on kaksipäinen jono, joka tukee sekä FIFO- että LIFO-periaatteita.

1. Mikä on Stack-tietorakenteen perusperiaate?

2. Mikä menetelmä lisää alkion pinon (stack) huipulle Javassa?

3. Mikä seuraavista Javan kokoelmista on nykyaikaisempi vaihtoehto Stack-luokalle?

4. Mitä pop()-metodi palauttaa Java:n Stack-luokassa?

question mark

Mikä on Stack-tietorakenteen perusperiaate?

Select the correct answer

question mark

Mikä menetelmä lisää alkion pinon (stack) huipulle Javassa?

Select the correct answer

question mark

Mikä seuraavista Javan kokoelmista on nykyaikaisempi vaihtoehto Stack-luokalle?

Select the correct answer

question mark

Mitä pop()-metodi palauttaa Java:n Stack-luokassa?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

bookPino-Tietorakenne Javassa

Pyyhkäise näyttääksesi valikon

Stack on tietorakenne, joka noudattaa viimeksi sisään, ensimmäisenä ulos (LIFO) -periaatetta. Sama periaate koskee myös Deque-tietorakennetta, johon tutustuit aiemmin, ja Java-kehittäjät suosittelevat käyttämään Deque-rakennetta, kun tietorakenteen tulee toimia LIFO-periaatteella. Stack-tietorakenne on vanhentunut eikä sitä suositella käytettäväksi nykyaikaisessa Java-kehityksessä.

Jotkin kokoelmat eivät enää ole suositeltavia ja ne on merkitty vanhentuneiksi.

Vanhentunut

Kun elementti on merkitty vanhentuneeksi, se tarkoittaa, että kirjaston tai ohjelmointikielen tekijät neuvovat välttämään sen käyttöä uudessa koodissa ja suosittelevat uusien menetelmien, luokkien tai lähestymistapojen käyttöönottoa, jotka voivat tarjota turvallisempia, tehokkaampia tai toiminnallisempia ratkaisuja.

Esimerkkinä on Vector-luokka Javassa. Sen metodit on merkitty vanhentuneiksi nykyaikaisempien kokoelmien, kuten ArrayList ja LinkedList, hyväksi. Jos ohjelmoija käyttää edelleen Vector-metodeja, kääntäjä voi antaa varoituksen siitä, että nämä metodit ovat vanhentuneita.

Esimerkki Javassa:

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

Tästä syystä ei suositella käyttämään tietorakennetta kuten Stack, mutta käsittelemme sitä tässä luvussa, koska se on mielenkiintoinen tietorakenne, jota käytetään esimerkiksi Javassa Stack-muisti.

Pino

Ytimekkäästi, tarkastellaan Stack-luokan metodeja:

Metodit

push(E element): lisää alkion pinon päälle.

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

Lisäys tapahtuu samalla tavalla kuin ArrayList:ssä, joten tarkastellaan tätä menetelmää yhdessä pop()-menetelmän kanssa:

pop(): poistaa ja palauttaa alkion pinon päältä.

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

Tämä menetelmä poistaa yhden alkion pinon päältä. Huomaa, että pop()-menetelmä poistaa viimeksi lisätyn alkion pinosta. Tämä on juuri se, miten LIFO-periaate toimii.

Voit myös tarkistaa, mikä alkio on pinon päällä:

peek(): palauttaa alkion pinon päältä ilman että sitä poistetaan.

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

Tällä menetelmällä tarkastellaan pinon päällimmäistä alkiota.

Käyttö

Tarkastellaan esimerkkiä Stack-tietorakenteen käytöstä selaimen sivuhistorian hallinnassa (ne eteenpäin ja taaksepäin nuolet, joita käytät usein).

Suunnitellaan selaimen historian toteutus ja toteutetaan kaksi painiketta vastaavat metodit (goBack() ja goForward()). Jos et ole varma, mistä painikkeista on kyse, tarkoitan näitä navigointipainikkeita:

Toteutetaan luokka, jossa on menetelmät näiden kahden painikkeen käyttämiseen hyödyntäen Stack-tietorakennetta.

Toimintaperiaate

Käytössäsi on kaksi pinoa ja String-muuttuja. Ensimmäinen pino tallentaa linkit, joita selaat napsauttamalla "takaisin"-nuolta. Toinen pino tallentaa linkit, joita selaat napsauttamalla "eteenpäin"-nuolta. Lisäksi käytössäsi on String-muuttuja, joka tallentaa nykyisen sivun linkin.

Tässä luokassa on neljä menetelmää: visitPage(), goBack(), goForward() ja getCurrentPage(). Käydään ne läpi vaiheittain.

visitPage()-menetelmä ohjaa meidät parametrina annettuun URL-osoitteeseen. Kun siirrytään uudelle sivulle, vanha linkki lisätään backStack-pinoon. forwardStack tyhjennetään, kun siirrytään uudelle sivulle.

Tarkastellaan toteutusta koodissa:

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

Näin voimme palata edelliselle sivulle, kun siirrytään uudelle sivulle.

Toteutetaan takaisin siirtymisen menetelmä. Se toimii seuraavasti: lisätään nykyinen linkki forwardStack-pinoon, sitten poistetaan tämä linkki backStack-pinosta ja asetetaan se currentUrl-muuttujaan.

Tarkastellaan toteutusta koodissa:

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

Muistutuksena, pop()-metodi poistaa alkion pinon päältä ja palauttaa sen. Tämän vuoksi tällä metodilla voimme suoraan asettaa URL-osoitteen arvon muuttujaan currentUrl.

Tarkistamme myös, että backStack ei ole tyhjä; muuten emme voi palata edelliseen linkkiin (koska sitä ei ole olemassa). Jos pino on tyhjä, tulostamme vastaavan viestin.

Samalla tavalla toteutamme metodin siirtymiselle seuraavalle sivulle. Vaihdamme yksinkertaisesti pinon alkioiden järjestystä:

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

Nyt jäljellä on vain getCurrentPage()-metodin toteutus, joka yksinkertaisesti palauttaa currentUrl-arvon.

Testaus

Seuraavaksi testataan tätä kaikkea main-metodissa. Käytetään visitPage()-metodia kolme kertaa varmistaaksemme, että nämä linkit tallentuvat historiaan. Sen jälkeen käytetään goBack()-metodia kahdesti ja lopuksi goForward()-metodia kerran varmistaaksemme metodien toimivuuden.

Tämän prosessin aikana seurataan tilaa getCurrentPage()-metodilla. Voit suorittaa alla olevan koodin ja myös kokeilla lisätä lisää linkkejä sekä käyttää eri metodeja testataksesi tämän luokan toiminnallisuutta:

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

Muista, että Stack-luokka on vanhentunut eikä sitä suositella käytettäväksi nykyaikaisessa Java-kehityksessä. Sen sijaan on parempi käyttää Deque-rakennetta, joka on tehokkaampi vaihtoehto. Tässä esimerkissä Stack on toteutettu LIFO-periaatteella, ja voit myös toteuttaa Deque-rakenteen, sillä se on kaksipäinen jono, joka tukee sekä FIFO- että LIFO-periaatteita.

1. Mikä on Stack-tietorakenteen perusperiaate?

2. Mikä menetelmä lisää alkion pinon (stack) huipulle Javassa?

3. Mikä seuraavista Javan kokoelmista on nykyaikaisempi vaihtoehto Stack-luokalle?

4. Mitä pop()-metodi palauttaa Java:n Stack-luokassa?

question mark

Mikä on Stack-tietorakenteen perusperiaate?

Select the correct answer

question mark

Mikä menetelmä lisää alkion pinon (stack) huipulle Javassa?

Select the correct answer

question mark

Mikä seuraavista Javan kokoelmista on nykyaikaisempi vaihtoehto Stack-luokalle?

Select the correct answer

question mark

Mitä pop()-metodi palauttaa Java:n Stack-luokassa?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4
some-alt