Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Jonorakenne Javassa | Osio
Javan Perustietorakenteet

Jonorakenne Javassa

Pyyhkäise näyttääksesi valikon

Aloitetaan Queue:lla. Kuvittele jono kaupassa alennusmyynnin aikana. Jonossa on 10 henkilöä; ensimmäinen henkilö on lähimpänä kaupan ovia ja kymmenes henkilö on kauimpana. Kun ensimmäinen henkilö astuu kauppaan, hän poistuu jonosta, jolloin koko jono siirtyy eteenpäin yhdellä henkilöllä. Java:n Queue toimii hyvin samanlaisella periaatteella.

Tällä tavoin voidaan toteuttaa erilaisia ohjelmia, joissa jonon logiikka on huolellisesti suunniteltu. Esimerkiksi suunnitelmien ja tehtävien hallintataulu.

Ensin tarkastellaan kuitenkin Queue:n perusmenetelmiä.

Queue on rajapinta, josta LinkedList-luokka perii ominaisuudet, ja tämä luokka on jo entuudestaan tuttu, joten käytämme tätä toteutusta.

Tällä tavoin käytetään rajapintaa olion tyyppinä, mutta olion toteutus on LinkedList, koska se on tämän olion tietty toteutus. (Muista, että et voi luoda olioita suoraan rajapinnasta).

Esimerkki:

Example.java

Example.java

1234
// `LinkedList` as implementation of the `List` interface: List<T> list = new LinkedList<>(); // `LinkedList` as implementation of the `Queue` interface: Queue<T> queue = new LinkedList<>();

Tällä tavalla sovelluksesta voidaan tehdä erittäin joustava käyttämällä erilaisia toteutuksia samasta rajapinnasta.

Palataan kuitenkin takaisin Queue-rajapinnan käyttömenetelmiin.

Menetelmät

Joitakin keskeisiä Queue-rajapinnan menetelmiä ovat:

  • add(element): lisää jonoon alkion, heittää poikkeuksen jos operaatio ei ole mahdollinen;
  • offer(element): lisää jonoon alkion, palauttaa true jos onnistuu tai false muuten.

Voit huomata, että nämä menetelmät tekevät pohjimmiltaan saman asian. Kuitenkin tärkein ero on offer-menetelmän turvallisuus. Jos alkiota ei voida lisätä oikein, offer-menetelmä ei heitä poikkeusta eikä pysäytä ohjelman suoritusta.

Tällä hetkellä tämä ominaisuus ei ole meille erityisen merkittävä, koska tavallisessa Queue-rakenteessa ei ole rajoituksia. On kuitenkin olemassa rakenne nimeltä BlockingQueue, jolla on rajoitus alkioiden määrässä; tällöin näillä menetelmillä on huomattava ero.

Tarkastellaan esimerkkiä:

Main.java

Main.java

1234567891011121314
package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.add("One"); queue.add("Two"); queue.add("Three"); System.out.println("Queue: " + queue); } }

Kuten huomaat, kun käytetään add()-metodia ja yritetään lisätä alkio, joka ei mahdu jonoon, ohjelma heittää virheen ja suoritus päättyy odottamattomasti.

Kokeillaan samaa toimintoa, mutta turvallisemmalla menetelmällä — offer():

Main.java

Main.java

1234567891011121314
package com.example; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(2); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); } }

Kuten huomaat, nyt elementtiä ei lisätty jonoon, mutta myöskään poikkeusta ei heitetty. Voimme siis todeta, että käsittelimme virheen hallitusti.

Poikkeuksia voi käsitellä eri tavoin esimerkiksi try-catch-rakenteella, mutta käsittelemme sitä myöhemmin.

Poistomenetelmät

  • remove(): poistaa ja palauttaa jonon alussa olevan alkion, heittää poikkeuksen jos jono on tyhjä;
  • poll(): poistaa ja palauttaa jonon alussa olevan alkion, palauttaa null jos jono on tyhjä.

Nämä menetelmät suorittavat täsmälleen saman toiminnon kuin jos ensimmäinen henkilö jonossa astuisi kauppaan ja poistuisi jonosta. Tässä toteutuu FIFO-periaate (First In, First Out). Toisin sanoen, ensimmäisenä jonoon lisätty alkio poistetaan ensimmäisenä.

Tässä näet myös näiden kahden menetelmän eron. poll()-menetelmää käytetään useammin kuin remove()-menetelmää, koska se on turvallisempi eikä heitä poikkeuksia.

Tarkastellaanpa esimerkkiä:

Main.java

Main.java

123456789101112131415
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.remove(); queue.remove(); System.out.println("Queue after removal operation: " + queue); } }

Kuten huomaat, ohjelma heittää NoSuchElementException-poikkeuksen, koska yritämme poistaa alkion tyhjästä jonosta.

Tällaisen poikkeuksen välttämiseksi on parempi käyttää poll()-metodia:

Main.java

Main.java

123456789101112131415
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); System.out.println("Queue: " + queue); queue.poll(); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }

Nyt olemme poistaneet alkion jonosta turvallisesti, eikä poikkeusta heitetty, kun yritimme poistaa alkion tyhjästä listasta.

poll()-metodin palauttamaa null-ominaisuutta voidaan hyödyntää esimerkiksi while()-silmukassa.

Tarkastellaan esimerkkiä:

Main.java

Main.java

1234567891011121314151617181920
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.poll() != null) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }

Tällä tavalla kaikki jonon alkiot voidaan poistaa silmukkaa käyttäen.

Muista, että ensimmäinen jonoon lisätty alkio on se, joka poistetaan ensimmäisenä! Esimerkiksi yllä olevassa esimerkissä alkio, jonka data on "One", poistettiin ensin.

Alla havainnollistetaan FIFO-periaatetta:

Main.java

Main.java

123456789101112131415161718
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); queue.poll(); System.out.println("Queue after removal operation: " + queue); } }

Voimme siirtyä menetelmiin, jotka palauttavat ensimmäisen ja viimeisen alkion:

  • element(): palauttaa, mutta ei poista, jonon alusta alkion, heittäen poikkeuksen jos jono on tyhjä;
  • peek(): palauttaa, mutta ei poista, jonon alusta alkion, palauttaen null, jos jono on tyhjä.

peek()-menetelmän käyttö on luotettavampi ja turvallisempi tapa, sillä se auttaa välttämään mahdolliset poikkeukset.

Tarkastellaan esimerkkiä käytöstä:

Main.java

Main.java

12345678910111213141516
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); System.out.println("Queue: " + queue); System.out.println("The first element in the queue: " + queue.peek()); System.out.println("Queue after the `peek()` method: " + queue); } }

Voit yhdistää tämän menetelmän muihin jonon menetelmiin.

Jos sinulla on jono, jossa on viisi alkiota ja sinun täytyy poistaa kaikki alkiot neljänteen asti (mukaan lukien), tarkastellaan tällaisen operaation toteutusta:

Main.java

Main.java

123456789101112131415161718192021
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (!queue.peek().equals("Four")) { queue.poll(); } queue.poll(); System.out.println("Queue after removal operation: " + queue); } }

Käytit silmukkaa, jonka ehto perustui peek()-metodiin.

Voit optimoida tämän silmukan merkittävästi käyttämällä contains()-metodia. Tämä metodi palauttaa arvon true, jos määritetty alkio on jonossa, ja false, jos se ei ole.

Parannetaan yllä olevaa koodia:

Main.java

Main.java

1234567891011121314151617181920
package com.example; import java.util.LinkedList; import java.util.Queue; public class Main { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("One"); queue.offer("Two"); queue.offer("Three"); queue.offer("Four"); queue.offer("Five"); System.out.println("Queue: " + queue); while (queue.contains("Four")) { queue.poll(); } System.out.println("Queue after removal operation: " + queue); } }

Tässä asetetaan yksi ehto while -silmukalle. Onnistuttiin poistamaan kaikki alkiot mukaan lukien "Four"-alkio.

1. Mikä on Queue Javassa?

2. Mikä rajapinta edustaa Queuea Java Collections Frameworkissa?

3. Mikä on offer()-metodin tarkoitus Queue-rajapinnassa?

4. Mitä poll()-metodi tekee Queue-rajapinnassa?

5. Mikä luokka Javan java.util.concurrent-paketissa edustaa rajattua estävää jonoa?

6. Mitä tapahtuu, jos yrität lisätä alkion täyteen jonoon käyttämällä add()-metodia?

question mark

Mikä on Queue Javassa?

Valitse oikea vastaus

question mark

Mikä rajapinta edustaa Queuea Java Collections Frameworkissa?

Valitse oikea vastaus

question mark

Mikä on offer()-metodin tarkoitus Queue-rajapinnassa?

Valitse oikea vastaus

question mark

Mitä poll()-metodi tekee Queue-rajapinnassa?

Valitse oikea vastaus

question mark

Mikä luokka Javan java.util.concurrent-paketissa edustaa rajattua estävää jonoa?

Valitse oikea vastaus

question mark

Mitä tapahtuu, jos yrität lisätä alkion täyteen jonoon käyttämällä add()-metodia?

Valitse oikea vastaus

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 9

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

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

Osio 1. Luku 9
some-alt