Luisengymnasium

Queue programmieren

Lernziele

Nach diesem Kapitel kannst du:

  • das Queue-Pattern in einem Praxis-Projekt anwenden (Bestellung aufgeben, versenden),
  • das Umschütt-Pattern erklären und implementieren (Suchen/Zählen ohne Queue zu zerstören),
  • erklären, warum Queue<int> nicht kompiliert und Wrapper-Klassen verwenden,
  • eine FulfillmentCenter-Klasse mit Queue entwerfen und implementieren.

Leitfrage: Wie suchst und zählst du in einer Queue, wenn du immer nur das erste Element sehen kannst?

Dein Lernweg

Bearbeite A1 und erweitere entweder deinen Shop aus Unit 1 (A2) oder repariere die Suche (A3). Beide Wege müssen einen vollständigen Vorher-/Nachher-Test enthalten. Der Kompetenzcheck gilt für alle. Stornierung, Fibonacci und Expressverwaltung sind Wahlvertiefungen.

Mermaid-Diagramm
Mermaid-Diagramm wird geladen…

Arbeitsweise: Abruffragen und Kompetenzchecks beantwortest du zuerst allein ohne Unterlagen und KI. Speichere deine eigene Antwort, bevor du die Rückmeldung öffnest. Im Übungsteil darfst du Hilfen nutzen; nenne anschließend, welche Hilfe du gebraucht hast. Bei jedem Programm: erst erwartete Ausgabe und einen Leerfall notieren, dann ausführen und vergleichen.

Voraussetzungen

Hinweis

Du solltest die 4 Queue-Methoden (enqueue, dequeue, front, isEmpty) und das FIFO-Prinzip aus Queue verstehen sicher beherrschen.

Übergang: Die Queue wird unbequem

Im letzten Kapitel war die Queue einfach: hinten anstellen, vorne bedienen. Für eine Warteschlange ist das perfekt.

Echte Programme fragen aber mehr: Wie viele Bestellungen sind offen? Gibt es eine bestimmte Bestellung? Kann ich filtern oder suchen?

Hier entsteht der Konflikt: Um eine Queue zu untersuchen, musst du Elemente entnehmen. Wenn du nicht aufpasst, ist die Queue danach leer.


Phase 1: Einstieg — Das Zähl-Problem

Hinweis

Retrieval-Check:

  1. Was passiert, wenn du alle Elemente einer Queue mit dequeue() entfernst?
  2. Was ist der Unterschied zwischen front() und dequeue()?
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Aufgabe: Wie viele Bestellungen sind offen?

Exploration – 4 Minuten allein, ohne KI: Skizziere eine Methode, die die Anzahl der Bestellungen zählt und danach dieselbe Reihenfolge erhält. Notiere deinen Versuch vor dem Aufklappen. Scheitert er, markiere genau den Schritt, an dem Daten verloren gehen.


Phase 2: Konzeptaufbau — Umschütt-Pattern und Praxis

Abruf 2 – ohne Nachlesen: Was muss nach einer nur lesenden Untersuchung der Queue erhalten sein? Warum ist eine Referenz auf ein Element noch keine Kopie des Elements?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Beim folgenden Beispiel ohne KI: Sage das Ergebnis vorher. Erkläre anschließend einer anderen Person, welche Zeile die Datenstruktur verändert. Erst dann ausführen.

2.1 Das Fulfillment-Center-Projekt

Wir entwickeln die Schnittstelle aus Unit 1 weiter: Aus bestellungAufgeben wird bestellungEingang. naechsteVersenden gibt jetzt eine Bestellung oder null zurück; die Ausgabe übernimmt Main. Übertrage deinen Code aus Unit 1 oder nutze das Gerüst. Die neue Aufgabe ist das erhaltende Zählen, nicht das erneute Abschreiben der beiden Grundmethoden.

Durchgaengiges Projekt: Online-Shop

Das Fulfillment Center verwaltet eingehende Bestellungen in einer Queue. Bestellungen werden in der Reihenfolge versendet, in der sie eingehen (FIFO).

Zwei Klassen:

  • Bestellung — speichert Kundenname, Produktname und Menge
  • FulfillmentCenter — verwaltet Bestellungen in einer Queue<Bestellung>
Mermaid-Diagramm
Mermaid-Diagramm wird geladen…

bestellungEingang() und naechsteVersenden() sind direkt:

public void bestellungEingang(String pKunde, String pProdukt, int pMenge)
{
    schlange.enqueue(new Bestellung(pKunde, pProdukt, pMenge));
}
 
public Bestellung naechsteVersenden()
{
    if (!schlange.isEmpty())
    {
        Bestellung b = schlange.front();
        schlange.dequeue();
        return b;
    }
    return null;
}

2.2 Das Umschütt-Pattern

Problem: anzahlOffene() muss alle Elemente zählen, ohne die Queue zu zerstören.

Lösung: Eine Hilfs-Queue. Jedes Element wird aus der Original-Queue entnommen, gezählt und in die Hilfs-Queue gesteckt. Am Ende werden alle Elemente zurückgeschüttet.

public int anzahlOffene()
{
    int count = 0;
    Queue<Bestellung> hilfe = new Queue<Bestellung>();
 
    // Umschütten: Original → Hilfe (dabei zählen)
    while (!schlange.isEmpty())
    {
        hilfe.enqueue(schlange.front());
        schlange.dequeue();
        count++;
    }
 
    // Zurückschütten: Hilfe → Original
    while (!hilfe.isEmpty())
    {
        schlange.enqueue(hilfe.front());
        hilfe.dequeue();
    }
 
    return count;
}

Teste den Unterschied — naiv vs. sicher:

IDE lädt…

Umschütt-Pattern
// Zählen/Suchen in einer Queue, ohne sie zu zerstören:
Queue<Typ> hilfe = new Queue<Typ>();
while (!original.isEmpty())
{
    Typ x = original.front();
    original.dequeue();
    // ... x verarbeiten (zählen, suchen, filtern) ...
    hilfe.enqueue(x);
}
// Zurückschütten
while (!hilfe.isEmpty())
{
    original.enqueue(hilfe.front());
    hilfe.dequeue();
}

Reflexionsfrage: Warum muss man die Elemente zurückschütten? Was wäre die Konsequenz, wenn man es vergisst?

Ruhige Sicherung: Der Bug und die Rettung

Tipp

Das Umschütt-Pattern besteht aus zwei gegensätzlichen Bewegungen:

SchrittWas passiert?Gefahr / Zweck
Herausschüttenfront() lesen, dequeue() entfernenDie Original-Queue wird leerer
Verarbeitenzählen, suchen, prüfenHier passiert die eigentliche Aufgabe
Zwischenspeichernhilfe.enqueue(x)Kein Element geht verloren
Zurückschüttenaus hilfe wieder in originalDie ursprüngliche Reihenfolge wird wiederhergestellt

Die zentrale Regel lautet: Jede Methode, die eine Queue untersucht, muss am Ende klären, ob die Queue erhalten bleiben soll.

2.3 Wrapper-Klassen — Queue<int> geht nicht

Was, wenn du Zahlen in einer Queue speichern willst?

Queue<int> zahlen = new Queue<int>();  // COMPILERFEHLER!

Problem: Generics (<...>) benötigen Referenztypen, nicht primitive Typen wie int oder double.

Lösung: Wrapper-Klassen — sie „verpacken" primitive Werte in Objekte.

PrimitivWrapper
intInteger
doubleDouble
booleanBoolean
Queue<Integer> zahlen = new Queue<Integer>();
zahlen.enqueue(42);    // Auto-Boxing: int → Integer automatisch
int x = zahlen.front(); // Auto-Unboxing: Integer → int automatisch

IDE lädt…

Zwei Mini-Checks vor der Übung

1. Original A,B,C: A und B sind in die Hilfs-Queue übertragen. Was ist jeweils vorne?

2. Original ist nach dem Zählen nicht leer. Reicht das als Korrektheitsnachweis?

Fading – Hilfen nach Bedarf


Hilfen für Zählen, Suchen und Filtern

Phase 3: Üben

Hinweis

Retrieval-Check:

  1. Was ist das Umschütt-Pattern?
  2. Warum kompiliert Queue<int> nicht?
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Abgabe-Aufgaben

Erwartungs-Check für A2/A3: Notiere vor jedem Lauf Inhalt und Reihenfolge. Nach wiederholtem Zählen müssen drei Bestellungen in derselben Reihenfolge vorhanden sein. Suche einmal nach einem mittleren Kunden, einmal nach einem unbekannten Namen, danach erneut nach dem ersten. Eine reine Ausgabe „true“ genügt nicht: Entnimm am Ende alle Bestellungen und vergleiche ihre vollständige Reihenfolge.

A1: Trace — Umschütt-Pattern (Pflicht)

Eine Queue enthält die Bestellungen Mueller, Schmidt, Weber, Fischer (in dieser Reihenfolge). Das Umschütt-Pattern wird ausgeführt, um die Anzahl zu zählen.

Zeichne den Zustand der Original-Queue und der Hilfs-Queue nach jedem Schleifendurchlauf.

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

A2: FulfillmentCenter erweitern (Wahlpflicht, AFB II)

Implementiere die Klasse FulfillmentCenter mit:

  • bestellungEingang(String pKunde, String pProdukt, int pMenge) — neue Bestellung erzeugen und enqueuen
  • naechsteVersenden() — nächste Bestellung versenden (front + dequeue, mit isEmpty-Check)
  • anzahlOffene() — mit Umschütt-Pattern zählen

IDE lädt…

A3: Suche erhält die Queue (Wahlpflicht, AFB II)

Der folgende Code soll prüfen, ob eine Bestellung von Kunde "Schmidt" in der Queue ist. Bei einem Treffer fehlen danach die davorliegenden Bestellungen; bei einem Nichttreffer ist die Queue leer. Finde und behebe den Fehler.

IDE lädt…

A4: Design — Bestellung stornieren (Vertiefung)

Implementiere bestellungStornieren(String kunde): Entferne alle Bestellungen mit diesem Kundennamen. Alle anderen Bestellungen sollen in der gleichen Reihenfolge bleiben. Gibt es keinen Treffer, bleibt die Queue unverändert. Teste auch zwei Bestellungen desselben Kunden.

Tipp: Umschütt-Pattern, aber die gesuchte Bestellung NICHT in die Hilfs-Queue schütten.

IDE lädt…

A5: Fibonacci mit Queue<Integer> (Vertiefung)

Erwartungs-Check: Für n=0 keine Ausgabe, für n=1 die 1, für n=5 die Folge 1,1,2,3,5. Verwende für diese Übung 0 ≤ n ≤ 20.

Implementiere eine Methode, die die ersten n Fibonacci-Zahlen in eine Queue<Integer> einfügt und danach alle ausgibt.

Fibonacci-Folge: 1, 1, 2, 3, 5, 8, 13, ... (jede Zahl ist die Summe der zwei vorherigen).

IDE lädt…


Kompetenzcheck – allein, 8–10 Minuten (Pflicht)

Beantworte die drei Aufgaben ohne Vorlage, Ausführen oder KI. Speichere deine erste Antwort vor dem Vergleich. Eine Partnerlösung ersetzt deine Antwort nicht.

  1. Eine Queue enthält A, B, C. Eine Suchmethode findet B und lässt B, C zurück. Erfüllt sie „Suchen ohne Veränderung“? Begründe.
  2. Skizziere eine Reparatur mit Hilfs-Queue. Erkläre, warum ein return beim ersten Treffer vor dem Wiederherstellen falsch wäre.
  3. Formuliere für Treffer, Nichttreffer und leere Queue je Ergebnis und erwartete Reihenfolge danach.
Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Neuer Versuch nach gezielter Übung

Queue K,L,K. Beschreibe eine Suche nach Z und danach nach K, die jeweils die erste passende Bestellung liefert und die Queue erhält. Gib beide Endzustände an.

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Phase 4: Transfer und Vernetzung

Transferaufgabe

Ohne KI: Notiere zuerst deine eigene Regel und einen erwarteten Ablauf. Erst danach nutze die Hilfen.

Online-Shop: Express-Bestellung

Durchgaengiges Projekt: Online-Shop

Manche Kunden zahlen fuer Express-Versand. Ihre Bestellung soll vor alle regulaeren Bestellungen gestellt werden.

Projektstand Online-Shop

Das FulfillmentCenter kann Bestellungen jetzt nicht nur abarbeiten, sondern auch untersuchen. Das ist ein echter Fortschritt: Die Datenstruktur bleibt erhalten, obwohl wir in sie hineinschauen.

Ein vollständiger Durchlauf kostet Umschütten. Die Grundoperationen hinten einfügen und vorne entnehmen brauchen das nicht. Ein zusätzlich gepflegter Zähler wäre eine Alternative für die Anzahl; bei jedem Einfügen und Entfernen müsste er korrekt aktualisiert werden.

Wahltransfer (AFB II–III): Entwirf eine Verwaltung mit zwei Queues: Express und regulär. Innerhalb jeder Gruppe gilt FIFO. Beim Versenden wird zuerst die Express-Queue bedient, sofern sie nicht leer ist.

Erwartungs-Check: Die Aufträge R1, E1, R2, E2 kommen in dieser Reihenfolge an. Erwartete Bedienung: E1, E2, R1, R2. Warum würde wiederholtes Einfügen ganz vorn stattdessen E2 vor E1 stellen?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Vernetzung

Heute gelöst: Du kannst eine Queue nicht nur benutzen, sondern kontrolliert untersuchen. Mit dem Umschütt-Pattern kannst du zählen, suchen oder filtern, ohne die Warteschlange am Ende leer zurückzulassen.

Noch offen: Bei der Queue haben wir viel Aufwand betrieben, um die ursprüngliche Reihenfolge zu erhalten. Es gibt aber Probleme, bei denen genau die umgekehrte Reihenfolge gewünscht ist: Die letzte Aktion soll zuerst zurückgenommen werden.

Nächster Schritt: Dafür brauchen wir kein FIFO, sondern LIFO. Die nächste Datenstruktur ist der Stack: oben drauflegen, oben wegnehmen, ideal für Undo.

Reflexion

Hinweis

Beantworte die Leitfrage: Wie suchst und zählst du in einer Queue, obwohl du nur vorne reinschauen kannst?

Textabgabe

Abgabe bis: 2027-07-31T23:59:00+02:00

Selbstdiagnose

  • Ich kann das Umschütt-Pattern erklären und anwenden.
  • Ich weiß, warum Queue<int> nicht funktioniert und verwende Queue<Integer>.
  • Ich kann eine FulfillmentCenter-Klasse mit Queue implementieren.

Partnerprüfung oder Solo-Erklärung (5 Minuten)

Erkläre 2 Minuten lang deine gewählte Methode. Dein Gegenüber prüft einen Randfall und fragt: „Warum bleibt die Reihenfolge hier erhalten oder ändert sich?“ Wechselt dann die Rollen. Allein: Schreibe die Erklärung und beantworte dieselbe Frage schriftlich. Vergleiche mit dem passenden Beispiel und verbessere einen unklaren Satz.

Selbstdiagnose: Welchen Ablauf, welche Begründung und welchen Randfall kannst du ohne Hilfe erklären? Nenne jeweils eine konkrete Aufgabe als Beleg. Wie sicher bist du (1–5)? Bei 1–2 bearbeitest du eine passende Hilfe und den neuen Versuch; bei 4–5 wählst du eine eigene Erweiterung.