Warteschlangen-Datenstruktur in Java
Beginnen wir mit einer Queue. Stellen Sie sich eine Warteschlange in einem Geschäft während eines Ausverkaufs vor. Es gibt 10 Personen; die erste Person steht näher an den Ladentüren als die anderen, und die 10. Person ist am weitesten entfernt. Wenn die erste Person das Geschäft betritt, verlässt sie die Warteschlange, wodurch die gesamte Schlange um eine Person nach vorne rückt. Die Java-Queue funktioniert nach einem sehr ähnlichen Prinzip.
Auf diese Weise können verschiedene Programme implementiert werden, bei denen die Logik der Warteschlange durchdacht ist. Zum Beispiel die Implementierung eines Boards mit Plänen und Aufgaben.
Zunächst betrachten wir jedoch die grundlegenden Methoden zur Arbeit mit einer Queue.
Queue ist ein Interface, von dem die Klasse LinkedList erbt, die Ihnen bereits bekannt ist. Daher werden wir diese Implementierung verwenden.
So verwenden Sie das Interface als Objekttyp, aber die Implementierung des Objekts ist LinkedList, da dies eine konkrete Implementierung dieses Objekts ist. (Beachten Sie, dass keine Objekte auf Basis eines Interface erstellt werden können).
Beispiel:
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<>();
Auf diese Weise kann die Anwendung sehr flexibel gestaltet werden, indem verschiedene Implementierungen derselben Schnittstelle verwendet werden.
Kehren wir jedoch zurück zu den Methoden zur Arbeit mit Queue.
Methoden
Einige wichtige Methoden des Queue-Interfaces sind:
add(element): Fügt ein Element zur Warteschlange hinzu und wirft eine Ausnahme, wenn die Operation nicht möglich ist;offer(element): Fügt ein Element zur Warteschlange hinzu und gibttruezurück, wenn erfolgreich, oderfalseandernfalls.
Es fällt auf, dass diese Methoden im Wesentlichen dasselbe tun. Der entscheidende Unterschied liegt jedoch in der Sicherheit der Methode offer. Im Falle eines fehlerhaft hinzugefügten Elements wirft die Methode offer keine Ausnahme und stoppt die Programmausführung nicht.
Derzeit ist dieses Merkmal für uns jedoch nicht von großem Interesse, da eine normale Queue nicht begrenzt ist. Es gibt jedoch eine Struktur namens BlockingQueue, die eine Beschränkung der Elementanzahl aufweist; in diesem Fall gibt es einen deutlichen Unterschied zwischen diesen Methoden.
Sehen wir uns ein Beispiel an:
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); } }
Wie Sie sehen, wirft das Programm beim Verwenden der Methode add() und dem Versuch, ein Element hinzuzufügen, das nicht in die Warteschlange passt, einen Fehler und beendet die Ausführung unerwartet.
Versuchen wir denselben Vorgang mit einer sichereren Methode — 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); } }
Wie Sie sehen, wurde das Element nicht zur Warteschlange hinzugefügt, aber es wurde auch keine Ausnahme ausgelöst. Daher können wir sagen, dass der Fehler ordnungsgemäß behandelt wurde.
Ausnahmen können auch mit einer Struktur wie try-catch behandelt werden, aber darauf gehen wir später ein.
Entfernungs-Methoden
remove(): Entfernt und gibt das Element am Anfang der Warteschlange zurück und löst eine Ausnahme aus, wenn die Warteschlange leer ist;poll(): Entfernt und gibt das Element am Anfang der Warteschlange zurück und gibtnullzurück, wenn die Warteschlange leer ist.
Diese Methoden erfüllen genau die Funktion, als ob die erste Person in der Warteschlange das Geschäft betritt und die Warteschlange verlässt. Hier greift das FIFO-Prinzip (First In, First Out). Das bedeutet, dass das Element, das zuerst hinzugefügt wurde, als erstes entfernt wird.
Hier lässt sich auch der Unterschied zwischen diesen beiden Methoden erkennen. Die Methode poll() wird häufiger verwendet als die Methode remove(), da sie sicherer ist und keine Ausnahmen auslöst.
Sehen wir uns ein Beispiel an:
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); } }
Wie Sie sehen können, wirft das Programm eine NoSuchElementException, da versucht wird, ein Element aus einer leeren Warteschlange zu entfernen.
Um eine solche Ausnahme zu vermeiden, ist es besser, die Methode poll() zu verwenden:
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); } }
Nun wurde ein Element sicher aus der Warteschlange entfernt, und es wurde keine Ausnahme ausgelöst, als versucht wurde, ein Element aus einer leeren Liste zu entfernen.
Die Eigenschaft, dass poll() null zurückgibt, kann beispielsweise in einer while()-Schleife genutzt werden.
Sehen wir uns ein Beispiel an:
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); } }
Auf diese Weise können alle Elemente aus der Warteschlange mithilfe einer Schleife entfernt werden.
Beachten Sie, dass das erste Element, das in die Warteschlange eingefügt wurde, auch als erstes entfernt wird! Im obigen Beispiel wurde beispielsweise das Element mit den Daten "One" zuerst entfernt.
Das FIFO-Prinzip wird unten demonstriert:
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); } }
Wir können nun zu den Methoden übergehen, die das erste und das letzte Element zurückgeben:
element(): Gibt das Element am Anfang der Warteschlange zurück, entfernt es jedoch nicht, und wirft eine Ausnahme, wenn die Warteschlange leer ist;peek(): Gibt das Element am Anfang der Warteschlange zurück, entfernt es jedoch nicht, und gibtnullzurück, wenn die Warteschlange leer ist.
Die Verwendung der Methode peek() ist eine zuverlässigere und sicherere Vorgehensweise, da sie hilft, potenzielle Ausnahmen zu vermeiden.
Sehen wir uns ein Anwendungsbeispiel an:
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); } }
Sie können diese Methode mit anderen Warteschlangenmethoden kombinieren.
Wenn Sie eine Warteschlange mit fünf Elementen haben und alle Elemente bis einschließlich zum vierten entfernen müssen, sehen wir uns die Implementierung einer solchen Operation an:
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); } }
Eine Schleife mit einer Bedingung basierend auf der Methode peek() wurde verwendet.
Diese Schleife kann deutlich optimiert werden, indem die Methode contains() eingesetzt wird. Diese Methode gibt true zurück, wenn das angegebene Element in der Queue vorhanden ist, und false, wenn nicht.
Die obige Code-Struktur wird nun verbessert:
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); } }
Hier setzen wir eine einzelne Bedingung für die while -Schleife. Es ist uns gelungen, alle Elemente bis einschließlich des Elements "Four" zu entfernen.
1. Was ist eine Queue in Java?
2. Welche Schnittstelle repräsentiert eine Queue im Java Collections Framework?
3. Was ist der Zweck der Methode offer() im Interface Queue?
4. Was macht die Methode poll() im Interface Queue?
5. Welche Klasse im Paket java.util.concurrent von Java repräsentiert eine beschränkte, blockierende Warteschlange?
6. Was passiert, wenn Sie versuchen, ein Element mit der Methode add() zu einer vollen Warteschlange hinzuzufügen?
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Großartig!
Completion Rate verbessert auf 4
Warteschlangen-Datenstruktur in Java
Swipe um das Menü anzuzeigen
Beginnen wir mit einer Queue. Stellen Sie sich eine Warteschlange in einem Geschäft während eines Ausverkaufs vor. Es gibt 10 Personen; die erste Person steht näher an den Ladentüren als die anderen, und die 10. Person ist am weitesten entfernt. Wenn die erste Person das Geschäft betritt, verlässt sie die Warteschlange, wodurch die gesamte Schlange um eine Person nach vorne rückt. Die Java-Queue funktioniert nach einem sehr ähnlichen Prinzip.
Auf diese Weise können verschiedene Programme implementiert werden, bei denen die Logik der Warteschlange durchdacht ist. Zum Beispiel die Implementierung eines Boards mit Plänen und Aufgaben.
Zunächst betrachten wir jedoch die grundlegenden Methoden zur Arbeit mit einer Queue.
Queue ist ein Interface, von dem die Klasse LinkedList erbt, die Ihnen bereits bekannt ist. Daher werden wir diese Implementierung verwenden.
So verwenden Sie das Interface als Objekttyp, aber die Implementierung des Objekts ist LinkedList, da dies eine konkrete Implementierung dieses Objekts ist. (Beachten Sie, dass keine Objekte auf Basis eines Interface erstellt werden können).
Beispiel:
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<>();
Auf diese Weise kann die Anwendung sehr flexibel gestaltet werden, indem verschiedene Implementierungen derselben Schnittstelle verwendet werden.
Kehren wir jedoch zurück zu den Methoden zur Arbeit mit Queue.
Methoden
Einige wichtige Methoden des Queue-Interfaces sind:
add(element): Fügt ein Element zur Warteschlange hinzu und wirft eine Ausnahme, wenn die Operation nicht möglich ist;offer(element): Fügt ein Element zur Warteschlange hinzu und gibttruezurück, wenn erfolgreich, oderfalseandernfalls.
Es fällt auf, dass diese Methoden im Wesentlichen dasselbe tun. Der entscheidende Unterschied liegt jedoch in der Sicherheit der Methode offer. Im Falle eines fehlerhaft hinzugefügten Elements wirft die Methode offer keine Ausnahme und stoppt die Programmausführung nicht.
Derzeit ist dieses Merkmal für uns jedoch nicht von großem Interesse, da eine normale Queue nicht begrenzt ist. Es gibt jedoch eine Struktur namens BlockingQueue, die eine Beschränkung der Elementanzahl aufweist; in diesem Fall gibt es einen deutlichen Unterschied zwischen diesen Methoden.
Sehen wir uns ein Beispiel an:
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); } }
Wie Sie sehen, wirft das Programm beim Verwenden der Methode add() und dem Versuch, ein Element hinzuzufügen, das nicht in die Warteschlange passt, einen Fehler und beendet die Ausführung unerwartet.
Versuchen wir denselben Vorgang mit einer sichereren Methode — 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); } }
Wie Sie sehen, wurde das Element nicht zur Warteschlange hinzugefügt, aber es wurde auch keine Ausnahme ausgelöst. Daher können wir sagen, dass der Fehler ordnungsgemäß behandelt wurde.
Ausnahmen können auch mit einer Struktur wie try-catch behandelt werden, aber darauf gehen wir später ein.
Entfernungs-Methoden
remove(): Entfernt und gibt das Element am Anfang der Warteschlange zurück und löst eine Ausnahme aus, wenn die Warteschlange leer ist;poll(): Entfernt und gibt das Element am Anfang der Warteschlange zurück und gibtnullzurück, wenn die Warteschlange leer ist.
Diese Methoden erfüllen genau die Funktion, als ob die erste Person in der Warteschlange das Geschäft betritt und die Warteschlange verlässt. Hier greift das FIFO-Prinzip (First In, First Out). Das bedeutet, dass das Element, das zuerst hinzugefügt wurde, als erstes entfernt wird.
Hier lässt sich auch der Unterschied zwischen diesen beiden Methoden erkennen. Die Methode poll() wird häufiger verwendet als die Methode remove(), da sie sicherer ist und keine Ausnahmen auslöst.
Sehen wir uns ein Beispiel an:
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); } }
Wie Sie sehen können, wirft das Programm eine NoSuchElementException, da versucht wird, ein Element aus einer leeren Warteschlange zu entfernen.
Um eine solche Ausnahme zu vermeiden, ist es besser, die Methode poll() zu verwenden:
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); } }
Nun wurde ein Element sicher aus der Warteschlange entfernt, und es wurde keine Ausnahme ausgelöst, als versucht wurde, ein Element aus einer leeren Liste zu entfernen.
Die Eigenschaft, dass poll() null zurückgibt, kann beispielsweise in einer while()-Schleife genutzt werden.
Sehen wir uns ein Beispiel an:
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); } }
Auf diese Weise können alle Elemente aus der Warteschlange mithilfe einer Schleife entfernt werden.
Beachten Sie, dass das erste Element, das in die Warteschlange eingefügt wurde, auch als erstes entfernt wird! Im obigen Beispiel wurde beispielsweise das Element mit den Daten "One" zuerst entfernt.
Das FIFO-Prinzip wird unten demonstriert:
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); } }
Wir können nun zu den Methoden übergehen, die das erste und das letzte Element zurückgeben:
element(): Gibt das Element am Anfang der Warteschlange zurück, entfernt es jedoch nicht, und wirft eine Ausnahme, wenn die Warteschlange leer ist;peek(): Gibt das Element am Anfang der Warteschlange zurück, entfernt es jedoch nicht, und gibtnullzurück, wenn die Warteschlange leer ist.
Die Verwendung der Methode peek() ist eine zuverlässigere und sicherere Vorgehensweise, da sie hilft, potenzielle Ausnahmen zu vermeiden.
Sehen wir uns ein Anwendungsbeispiel an:
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); } }
Sie können diese Methode mit anderen Warteschlangenmethoden kombinieren.
Wenn Sie eine Warteschlange mit fünf Elementen haben und alle Elemente bis einschließlich zum vierten entfernen müssen, sehen wir uns die Implementierung einer solchen Operation an:
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); } }
Eine Schleife mit einer Bedingung basierend auf der Methode peek() wurde verwendet.
Diese Schleife kann deutlich optimiert werden, indem die Methode contains() eingesetzt wird. Diese Methode gibt true zurück, wenn das angegebene Element in der Queue vorhanden ist, und false, wenn nicht.
Die obige Code-Struktur wird nun verbessert:
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); } }
Hier setzen wir eine einzelne Bedingung für die while -Schleife. Es ist uns gelungen, alle Elemente bis einschließlich des Elements "Four" zu entfernen.
1. Was ist eine Queue in Java?
2. Welche Schnittstelle repräsentiert eine Queue im Java Collections Framework?
3. Was ist der Zweck der Methode offer() im Interface Queue?
4. Was macht die Methode poll() im Interface Queue?
5. Welche Klasse im Paket java.util.concurrent von Java repräsentiert eine beschränkte, blockierende Warteschlange?
6. Was passiert, wenn Sie versuchen, ein Element mit der Methode add() zu einer vollen Warteschlange hinzuzufügen?
Danke für Ihr Feedback!