Kösdatastruktur i Java
Låt oss börja med en Queue. Föreställ dig en kö i en butik under en rea. Det finns 10 personer; den första personen står närmast butikens dörrar och den tionde personen står längst bort. När den första personen går in i butiken, lämnar den kön, vilket gör att hela kön flyttas framåt med en person. Java Queue fungerar enligt en mycket liknande princip.
På detta sätt kan du implementera olika program där könslogiken är väl genomtänkt. Till exempel att implementera en tavla med planer och uppgifter.
Men först, låt oss titta på de grundläggande metoderna för att arbeta med en Queue.
Queue är ett interface som LinkedList-klassen ärver från, vilket du redan är bekant med, så vi kommer att använda denna implementation.
På detta sätt använder du interfacet som objektets typ, men objektets implementation kommer att vara LinkedList eftersom det är en specifik implementation av detta objekt. (Kom ihåg att du inte kan skapa objekt baserat på ett interface).
Exempel:
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å detta sätt kan du göra vår applikation mycket flexibel genom att använda olika implementationer av samma gränssnitt.
Men låt oss återgå till metoder för att arbeta med Queue.
Metoder
Några viktiga metoder i gränssnittet Queue är:
add(element): lägger till ett element i kön, kastar ett undantag om operationen inte är möjlig;offer(element): lägger till ett element i kön, returnerartrueom det lyckas ellerfalseannars.
Du kan märka att dessa metoder i huvudsak gör samma sak. Den avgörande skillnaden är dock säkerheten hos offer-metoden. Vid felaktigt tillagt element kommer offer-metoden inte att kasta ett undantag och inte stoppa programmets körning.
Men för tillfället är denna egenskap inte av stort intresse för oss, eftersom en vanlig Queue inte är begränsad. Det finns dock en struktur som kallas BlockingQueue, som har en begränsning på antalet element; i det fallet kommer dessa metoder att ha en påtaglig skillnad.
Låt oss titta på ett exempel:
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 använder metoden add() och försöker lägga till ett element som inte får plats i kön, kastar programmet ett fel och avslutar exekveringen oväntat.
Låt oss prova samma operation men med en säkrare metod — 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, nu lades inte elementet till i kön, men det kastades inte heller något undantag. Vi kan alltså säga att vi hanterade felet på ett smidigt sätt.
Du kan hantera undantag på olika sätt med en struktur som try-catch, men det kommer vi att diskutera senare.
Borttagningsmetoder
remove(): tar bort och returnerar elementet från början av kön, kastar ett undantag om kön är tom;poll(): tar bort och returnerar elementet från början av kön, returnerarnullom kön är tom.
Dessa metoder utför exakt samma funktion som om första personen i kön gick in i butiken och lämnade kön. Det är här FIFO-principen (First In, First Out) gäller. Det vill säga, det element som lades till först i kön kommer att vara det första som tas bort.
Här kan du också se skillnaden mellan dessa två metoder. Metoden poll() används oftare än remove() eftersom den är säkrare och inte kastar undantag.
Låt oss titta på ett exempel:
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 kastar programmet ett NoSuchElementException eftersom vi försöker ta bort ett element från en tom kö.
För att undvika ett sådant undantag är det bättre att använda metoden poll():
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); } }
Nu har vi säkert tagit bort ett element från kön, och inget undantag kastades när vi försökte ta bort ett element från en tom lista.
Att poll() returnerar null kan till exempel användas i en while()-loop.
Låt oss titta på ett exempel:
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å detta sätt kan alla element tas bort från kön med hjälp av en loop.
Observera att det första elementet som lades till i kön är det som tas bort först! Till exempel, i exemplet ovan togs elementet med data "One" bort först.
FIFO-principen illustreras nedan:
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å vidare till metoderna som returnerar det första och sista elementet:
element(): returnerar, men tar inte bort, elementet från början av kön, kastar ett undantag om kön är tom;peek(): returnerar, men tar inte bort, elementet från början av kön, returnerarnullom kön är tom.
Att använda metoden peek() är ett mer tillförlitligt och säkrare tillvägagångssätt, eftersom det hjälper till att undvika potentiella undantag.
Låt oss titta på ett exempel på användning:
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 kombinera denna metod med andra kö-metoder.
Om du har en kö med fem element och behöver ta bort alla element fram till det fjärde (inklusive), låt oss titta på implementeringen av en sådan operation:
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 använde en loop med ett villkor baserat på metoden peek().
Du kan avsevärt optimera denna loop genom att använda metoden contains(). Denna metod returnerar true om det angivna elementet finns i kön och false om det inte gör det.
Låt oss förbättra koden ovan:
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); } }
Här ställer vi in ett enda villkor för while-loopen. Vi lyckades ta bort alla element upp till och med elementet "Four".
1. Vad är en Queue i Java?
2. Vilket interface representerar en Queue i Java Collections Framework?
3. Vad är syftet med metoden offer() i gränssnittet Queue?
4. Vad gör metoden poll() i gränssnittet Queue?
5. Vilken klass i Javas paket java.util.concurrent representerar en begränsad blockerande kö?
6. Vad händer om du försöker lägga till ett element i en full kö med metoden add()?
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
Fantastiskt!
Completion betyg förbättrat till 4
Kösdatastruktur i Java
Svep för att visa menyn
Låt oss börja med en Queue. Föreställ dig en kö i en butik under en rea. Det finns 10 personer; den första personen står närmast butikens dörrar och den tionde personen står längst bort. När den första personen går in i butiken, lämnar den kön, vilket gör att hela kön flyttas framåt med en person. Java Queue fungerar enligt en mycket liknande princip.
På detta sätt kan du implementera olika program där könslogiken är väl genomtänkt. Till exempel att implementera en tavla med planer och uppgifter.
Men först, låt oss titta på de grundläggande metoderna för att arbeta med en Queue.
Queue är ett interface som LinkedList-klassen ärver från, vilket du redan är bekant med, så vi kommer att använda denna implementation.
På detta sätt använder du interfacet som objektets typ, men objektets implementation kommer att vara LinkedList eftersom det är en specifik implementation av detta objekt. (Kom ihåg att du inte kan skapa objekt baserat på ett interface).
Exempel:
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å detta sätt kan du göra vår applikation mycket flexibel genom att använda olika implementationer av samma gränssnitt.
Men låt oss återgå till metoder för att arbeta med Queue.
Metoder
Några viktiga metoder i gränssnittet Queue är:
add(element): lägger till ett element i kön, kastar ett undantag om operationen inte är möjlig;offer(element): lägger till ett element i kön, returnerartrueom det lyckas ellerfalseannars.
Du kan märka att dessa metoder i huvudsak gör samma sak. Den avgörande skillnaden är dock säkerheten hos offer-metoden. Vid felaktigt tillagt element kommer offer-metoden inte att kasta ett undantag och inte stoppa programmets körning.
Men för tillfället är denna egenskap inte av stort intresse för oss, eftersom en vanlig Queue inte är begränsad. Det finns dock en struktur som kallas BlockingQueue, som har en begränsning på antalet element; i det fallet kommer dessa metoder att ha en påtaglig skillnad.
Låt oss titta på ett exempel:
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 använder metoden add() och försöker lägga till ett element som inte får plats i kön, kastar programmet ett fel och avslutar exekveringen oväntat.
Låt oss prova samma operation men med en säkrare metod — 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, nu lades inte elementet till i kön, men det kastades inte heller något undantag. Vi kan alltså säga att vi hanterade felet på ett smidigt sätt.
Du kan hantera undantag på olika sätt med en struktur som try-catch, men det kommer vi att diskutera senare.
Borttagningsmetoder
remove(): tar bort och returnerar elementet från början av kön, kastar ett undantag om kön är tom;poll(): tar bort och returnerar elementet från början av kön, returnerarnullom kön är tom.
Dessa metoder utför exakt samma funktion som om första personen i kön gick in i butiken och lämnade kön. Det är här FIFO-principen (First In, First Out) gäller. Det vill säga, det element som lades till först i kön kommer att vara det första som tas bort.
Här kan du också se skillnaden mellan dessa två metoder. Metoden poll() används oftare än remove() eftersom den är säkrare och inte kastar undantag.
Låt oss titta på ett exempel:
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 kastar programmet ett NoSuchElementException eftersom vi försöker ta bort ett element från en tom kö.
För att undvika ett sådant undantag är det bättre att använda metoden poll():
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); } }
Nu har vi säkert tagit bort ett element från kön, och inget undantag kastades när vi försökte ta bort ett element från en tom lista.
Att poll() returnerar null kan till exempel användas i en while()-loop.
Låt oss titta på ett exempel:
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å detta sätt kan alla element tas bort från kön med hjälp av en loop.
Observera att det första elementet som lades till i kön är det som tas bort först! Till exempel, i exemplet ovan togs elementet med data "One" bort först.
FIFO-principen illustreras nedan:
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å vidare till metoderna som returnerar det första och sista elementet:
element(): returnerar, men tar inte bort, elementet från början av kön, kastar ett undantag om kön är tom;peek(): returnerar, men tar inte bort, elementet från början av kön, returnerarnullom kön är tom.
Att använda metoden peek() är ett mer tillförlitligt och säkrare tillvägagångssätt, eftersom det hjälper till att undvika potentiella undantag.
Låt oss titta på ett exempel på användning:
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 kombinera denna metod med andra kö-metoder.
Om du har en kö med fem element och behöver ta bort alla element fram till det fjärde (inklusive), låt oss titta på implementeringen av en sådan operation:
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 använde en loop med ett villkor baserat på metoden peek().
Du kan avsevärt optimera denna loop genom att använda metoden contains(). Denna metod returnerar true om det angivna elementet finns i kön och false om det inte gör det.
Låt oss förbättra koden ovan:
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); } }
Här ställer vi in ett enda villkor för while-loopen. Vi lyckades ta bort alla element upp till och med elementet "Four".
1. Vad är en Queue i Java?
2. Vilket interface representerar en Queue i Java Collections Framework?
3. Vad är syftet med metoden offer() i gränssnittet Queue?
4. Vad gör metoden poll() i gränssnittet Queue?
5. Vilken klass i Javas paket java.util.concurrent representerar en begränsad blockerande kö?
6. Vad händer om du försöker lägga till ett element i en full kö med metoden add()?
Tack för dina kommentarer!