Kødatastruktur i Java
La oss starte med en Queue. Tenk deg en kø i en butikk under et salg. Det er 10 personer; den første personen står nærmest butikkdørene sammenlignet med de andre, og den 10. personen står lengst unna. Når den første personen går inn i butikken, forlater vedkommende køen, og hele køen flyttes dermed én person fremover. Java Queue fungerer etter et veldig lignende prinsipp.
På denne måten kan du implementere ulike programmer der kølogikken er gjennomtenkt. For eksempel å implementere et tavle med planer og oppgaver.
Men først, la oss se på de grunnleggende metodene for å arbeide med en Queue.
Queue er et interface som LinkedList-klassen arver fra, som du allerede er kjent med, så vi vil bruke denne implementasjonen.
På denne måten bruker du interface som objektets type, men objektets implementasjon vil være LinkedList fordi det er en spesifikk implementasjon av dette objektet. (Husk at du ikke kan opprette objekter basert på et interface).
Eksempel:
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<>();
På denne måten kan du gjøre applikasjonen svært fleksibel ved å bruke ulike implementasjoner av det samme grensesnittet.
Men la oss gå tilbake til metodene for å arbeide med Queue.
Metoder
Noen sentrale metoder i Queue-grensesnittet er:
add(element): legger til et element i køen, kaster et unntak hvis operasjonen ikke er mulig;offer(element): legger til et element i køen, returnerertruehvis vellykket ellerfalseellers.
Du kan merke at disse metodene i hovedsak gjør det samme. Den viktigste forskjellen er imidlertid sikkerheten til offer-metoden. Dersom et element ikke kan legges til, vil offer-metoden ikke kaste et unntak og vil ikke stoppe programmets kjøring.
Akkurat nå er ikke denne egenskapen spesielt interessant for oss, siden en vanlig Queue ikke har noen begrensning. Det finnes imidlertid en struktur kalt BlockingQueue, som har en begrensning på antall elementer; i slike tilfeller vil disse metodene ha en merkbar forskjell.
La oss se på et eksempel:
Main.java
1234567891011121314package 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); } }
Som du kan se, når du bruker add()-metoden og prøver å legge til et element som ikke får plass i køen, kaster programmet en feil og avslutter kjøringen uventet.
La oss prøve den samme operasjonen, men med en tryggere metode — offer():
Main.java
1234567891011121314package 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); } }
Som du kan se, ble elementet ikke lagt til i køen, men det ble heller ikke kastet et unntak. Vi kan derfor si at vi håndterte feilen på en kontrollert måte.
Du kan håndtere unntak på andre måter ved å bruke en struktur som try-catch, men dette vil vi diskutere senere.
Fjerningsmetoder
remove(): fjerner og returnerer elementet fra starten av køen, og kaster et unntak hvis køen er tom;poll(): fjerner og returnerer elementet fra starten av køen, og returnerernullhvis køen er tom.
Disse metodene utfører nøyaktig den funksjonen som om første person i køen gikk inn i butikken og forlot køen. Dette er hvor FIFO-prinsippet (First In, First Out) gjelder. Med andre ord, elementet som ble lagt til først i køen vil være det første som fjernes.
Her kan du også se forskjellen mellom disse to metodene. Metoden poll() brukes oftere enn remove() fordi den er tryggere og ikke kaster unntak.
La oss se på et eksempel:
Main.java
123456789101112131415package 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); } }
Som du kan se, kaster programmet en NoSuchElementException fordi vi prøver å fjerne et element fra en tom kø.
For å unngå en slik unntak, er det bedre å bruke poll()-metoden:
Main.java
123456789101112131415package 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); } }
Nå har vi fjernet et element fra køen på en sikker måte, og ingen unntak ble kastet da vi prøvde å fjerne et element fra en tom liste.
At poll() returnerer null kan for eksempel brukes i en while()-løkke.
La oss se på et eksempel:
Main.java
1234567891011121314151617181920package 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); } }
På denne måten kan alle elementene fjernes fra køen ved hjelp av en løkke.
Husk at det første elementet som kom inn i køen er det som fjernes først! For eksempel, i eksempelet ovenfor ble elementet med data "One" fjernet først.
FIFO-prinsippet illustreres nedenfor:
Main.java
123456789101112131415161718package 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); } }
Vi kan gå videre til metodene som returnerer det første og siste elementet:
element(): returnerer, men fjerner ikke, elementet fra starten av køen, og kaster et unntak hvis køen er tom;peek(): returnerer, men fjerner ikke, elementet fra starten av køen, og returnerernullhvis køen er tom.
Å bruke peek()-metoden er en mer pålitelig og tryggere tilnærming, da det bidrar til å unngå potensielle unntak.
La oss se på et eksempel på bruk:
Main.java
12345678910111213141516package 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); } }
Du kan kombinere denne metoden med andre kømetoder.
Hvis du har en kø med fem elementer og du trenger å fjerne alle elementene frem til det fjerde (inkludert), la oss se på implementeringen av en slik operasjon:
Main.java
123456789101112131415161718192021package 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); } }
Du brukte en løkke med en betingelse basert på peek()-metoden.
Du kan optimalisere denne løkken betydelig ved å bruke contains()-metoden. Denne metoden returnerer true hvis det angitte elementet finnes i køen, og false hvis det ikke gjør det.
La oss forbedre koden ovenfor:
Main.java
1234567891011121314151617181920package 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); } }
Her setter vi én enkelt betingelse for while-løkka. Vi klarte å fjerne alle elementene opp til og med elementet "Four".
1. Hva er en Queue i Java?
2. Hvilket grensesnitt representerer en Queue i Java Collections Framework?
3. Hva er formålet med offer()-metoden i Queue-grensesnittet?
4. Hva gjør poll()-metoden i Queue-grensesnittet?
5. Hvilken klasse i Javas java.util.concurrent-pakke representerer en begrenset blokkerende kø?
6. Hva skjer hvis du prøver å legge til et element i en full kø ved å bruke add()-metoden?
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
Can you explain more about the difference between add() and offer() methods?
How does the FIFO principle work in a real-world queue?
What are some practical uses of the Queue interface in Java?
Fantastisk!
Completion rate forbedret til 4
Kødatastruktur i Java
Sveip for å vise menyen
La oss starte med en Queue. Tenk deg en kø i en butikk under et salg. Det er 10 personer; den første personen står nærmest butikkdørene sammenlignet med de andre, og den 10. personen står lengst unna. Når den første personen går inn i butikken, forlater vedkommende køen, og hele køen flyttes dermed én person fremover. Java Queue fungerer etter et veldig lignende prinsipp.
På denne måten kan du implementere ulike programmer der kølogikken er gjennomtenkt. For eksempel å implementere et tavle med planer og oppgaver.
Men først, la oss se på de grunnleggende metodene for å arbeide med en Queue.
Queue er et interface som LinkedList-klassen arver fra, som du allerede er kjent med, så vi vil bruke denne implementasjonen.
På denne måten bruker du interface som objektets type, men objektets implementasjon vil være LinkedList fordi det er en spesifikk implementasjon av dette objektet. (Husk at du ikke kan opprette objekter basert på et interface).
Eksempel:
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<>();
På denne måten kan du gjøre applikasjonen svært fleksibel ved å bruke ulike implementasjoner av det samme grensesnittet.
Men la oss gå tilbake til metodene for å arbeide med Queue.
Metoder
Noen sentrale metoder i Queue-grensesnittet er:
add(element): legger til et element i køen, kaster et unntak hvis operasjonen ikke er mulig;offer(element): legger til et element i køen, returnerertruehvis vellykket ellerfalseellers.
Du kan merke at disse metodene i hovedsak gjør det samme. Den viktigste forskjellen er imidlertid sikkerheten til offer-metoden. Dersom et element ikke kan legges til, vil offer-metoden ikke kaste et unntak og vil ikke stoppe programmets kjøring.
Akkurat nå er ikke denne egenskapen spesielt interessant for oss, siden en vanlig Queue ikke har noen begrensning. Det finnes imidlertid en struktur kalt BlockingQueue, som har en begrensning på antall elementer; i slike tilfeller vil disse metodene ha en merkbar forskjell.
La oss se på et eksempel:
Main.java
1234567891011121314package 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); } }
Som du kan se, når du bruker add()-metoden og prøver å legge til et element som ikke får plass i køen, kaster programmet en feil og avslutter kjøringen uventet.
La oss prøve den samme operasjonen, men med en tryggere metode — offer():
Main.java
1234567891011121314package 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); } }
Som du kan se, ble elementet ikke lagt til i køen, men det ble heller ikke kastet et unntak. Vi kan derfor si at vi håndterte feilen på en kontrollert måte.
Du kan håndtere unntak på andre måter ved å bruke en struktur som try-catch, men dette vil vi diskutere senere.
Fjerningsmetoder
remove(): fjerner og returnerer elementet fra starten av køen, og kaster et unntak hvis køen er tom;poll(): fjerner og returnerer elementet fra starten av køen, og returnerernullhvis køen er tom.
Disse metodene utfører nøyaktig den funksjonen som om første person i køen gikk inn i butikken og forlot køen. Dette er hvor FIFO-prinsippet (First In, First Out) gjelder. Med andre ord, elementet som ble lagt til først i køen vil være det første som fjernes.
Her kan du også se forskjellen mellom disse to metodene. Metoden poll() brukes oftere enn remove() fordi den er tryggere og ikke kaster unntak.
La oss se på et eksempel:
Main.java
123456789101112131415package 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); } }
Som du kan se, kaster programmet en NoSuchElementException fordi vi prøver å fjerne et element fra en tom kø.
For å unngå en slik unntak, er det bedre å bruke poll()-metoden:
Main.java
123456789101112131415package 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); } }
Nå har vi fjernet et element fra køen på en sikker måte, og ingen unntak ble kastet da vi prøvde å fjerne et element fra en tom liste.
At poll() returnerer null kan for eksempel brukes i en while()-løkke.
La oss se på et eksempel:
Main.java
1234567891011121314151617181920package 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); } }
På denne måten kan alle elementene fjernes fra køen ved hjelp av en løkke.
Husk at det første elementet som kom inn i køen er det som fjernes først! For eksempel, i eksempelet ovenfor ble elementet med data "One" fjernet først.
FIFO-prinsippet illustreres nedenfor:
Main.java
123456789101112131415161718package 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); } }
Vi kan gå videre til metodene som returnerer det første og siste elementet:
element(): returnerer, men fjerner ikke, elementet fra starten av køen, og kaster et unntak hvis køen er tom;peek(): returnerer, men fjerner ikke, elementet fra starten av køen, og returnerernullhvis køen er tom.
Å bruke peek()-metoden er en mer pålitelig og tryggere tilnærming, da det bidrar til å unngå potensielle unntak.
La oss se på et eksempel på bruk:
Main.java
12345678910111213141516package 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); } }
Du kan kombinere denne metoden med andre kømetoder.
Hvis du har en kø med fem elementer og du trenger å fjerne alle elementene frem til det fjerde (inkludert), la oss se på implementeringen av en slik operasjon:
Main.java
123456789101112131415161718192021package 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); } }
Du brukte en løkke med en betingelse basert på peek()-metoden.
Du kan optimalisere denne løkken betydelig ved å bruke contains()-metoden. Denne metoden returnerer true hvis det angitte elementet finnes i køen, og false hvis det ikke gjør det.
La oss forbedre koden ovenfor:
Main.java
1234567891011121314151617181920package 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); } }
Her setter vi én enkelt betingelse for while-løkka. Vi klarte å fjerne alle elementene opp til og med elementet "Four".
1. Hva er en Queue i Java?
2. Hvilket grensesnitt representerer en Queue i Java Collections Framework?
3. Hva er formålet med offer()-metoden i Queue-grensesnittet?
4. Hva gjør poll()-metoden i Queue-grensesnittet?
5. Hvilken klasse i Javas java.util.concurrent-pakke representerer en begrenset blokkerende kø?
6. Hva skjer hvis du prøver å legge til et element i en full kø ved å bruke add()-metoden?
Takk for tilbakemeldingene dine!