Menu
Coddy logo textTech

Iteratormuster

Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 76 von 87.

Das Iterator Pattern ist ein Verhaltensentwurfsmuster, das eine Möglichkeit bietet, auf die Elemente einer Sammlung nacheinander zuzugreifen, ohne ihre zugrunde liegende Struktur offenzulegen. Unabhängig davon, ob du mit einem Array, einer verketteten Liste oder einem Baum arbeitest, bietet dir der Iterator eine einheitliche Möglichkeit, die Elemente zu durchlaufen.

Das Muster trennt die Traversierungslogik von der Sammlung selbst. Es umfasst zwei Hauptkomponenten: eine Iterator-Schnittstelle, die Methoden zum Durchlaufen von Elementen definiert, und ein Iterable (oder Aggregate), das Iteratoren für seine Sammlung erstellt:

interface Iterator<T> {
    boolean hasNext();
    T next();
}

interface Container<T> {
    Iterator<T> createIterator();
}

class BookShelf implements Container<String> {
    private String[] books;
    private int count = 0;
    
    public BookShelf(int size) {
        books = new String[size];
    }
    
    public void addBook(String book) {
        books[count++] = book;
    }
    
    public Iterator<String> createIterator() {
        return new BookIterator();
    }
    
    private class BookIterator implements Iterator<String> {
        private int index = 0;
        
        public boolean hasNext() {
            return index < count;
        }
        
        public String next() {
            return books[index++];
        }
    }
}

Der Iterator verwaltet seinen eigenen Traversierungszustand, sodass mehrere Iteratoren dieselbe Sammlung unabhängig voneinander durchlaufen können. Clients verwenden den Iterator, ohne zu wissen, wie die Sammlung ihre Daten speichert:

BookShelf shelf = new BookShelf(3);
shelf.addBook("Design Patterns");
shelf.addBook("Clean Code");

Iterator<String> iterator = shelf.createIterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Javas integrierte Schnittstellen Iterable und Iterator folgen genau diesem Muster. Deshalb kannst du erweiterte for-Schleifen mit jeder Klasse verwenden, die Iterable implementiert. Das Iterator-Muster ist unverzichtbar, wenn du mehrere Traversierungsmethoden bereitstellen oder komplexe interne Strukturen vor dem Client-Code verbergen musst.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Playlist-System mit dem Iterator Pattern! Du erstellst eine Musik-Playlist, die Songs speichert und einen benutzerdefinierten Iterator bereitstellt, um sie sequenziell zu durchlaufen, ohne offenzulegen, wie die Songs intern gespeichert werden. Dies ist ein perfekter Anwendungsfall für das Iterator Pattern, mit dem Benutzer deine Sammlung über eine klare, einheitliche Schnittstelle durchsuchen können.

Du organisierst deinen Code auf vier Dateien:

  • Iterator.java: Definiere deine generische Iterator<T>-Schnittstelle mit zwei Methoden: hasNext(), die einen booleschen Wert zurückgibt, der angibt, ob weitere Elemente vorhanden sind, und next(), die das nächste Element vom Typ T zurückgibt.
  • Playlist.java: Erstelle die Aggregatklasse, die deine Songs enthält. Deine Playlist sollte Songs in einem String-Array mit einer festen Kapazität speichern (die an den Konstruktor übergeben wird) und verfolgen, wie viele Songs hinzugefügt wurden. Füge eine addSong(String song)-Methode hinzu, um Songs zur Playlist hinzuzufügen.

    Deine Playlist benötigt eine createIterator()-Methode, die einen Iterator<String> zurückgibt. Implementiere dies, indem du eine private innere Klasse namens PlaylistIterator erstellst, die deine Iterator-Schnittstelle implementiert. Dieser innere Iterator verwaltet seine eigene Indexposition und durchläuft das Songs-Array, wobei er jeden Song in der richtigen Reihenfolge zurückgibt.

  • Song.java: Erstelle eine einfache Song-Klasse, die einen Songtitel kapselt. Sie sollte einen Konstruktor haben, der den Titel (String) entgegennimmt, sowie eine getTitle()-Methode und eine toString()-Methode, die Playing: [title] zurückgibt.
  • Main.java: Führe dein Iterator-System zusammen! Du erhältst eine Eingabe: eine durch Kommas getrennte Liste von Songtiteln (zum Beispiel: Bohemian Rhapsody,Stairway to Heaven,Hotel California).

    Erstelle eine Playlist mit einer Kapazität für 10 Songs. Verarbeite die Eingabe und füge jeden Songtitel zur Playlist hinzu. Rufe anschließend einen Iterator von der Playlist ab und verwende ihn, um alle Songs zu durchlaufen. Gib dabei jeden Song in einem Song-Objekt gekapselt aus (das als Playing: [title] angezeigt wird).

    Nachdem alle Songs durchlaufen wurden, gib Playlist complete! in einer neuen Zeile aus.

Du erhältst eine Eingabe: eine durch Kommas getrennte Zeichenkette mit Songtiteln.

Beispielsweise würde deine Ausgabe bei der Eingabe Yesterday,Imagine,Let It Be folgendermaßen aussehen:

Playing: Yesterday
Playing: Imagine
Playing: Let It Be
Playlist complete!

Beachte, wie deine Main-Klasse die Methoden hasNext() und next() des Iterators verwendet, um die Playlist zu durchlaufen, ohne etwas über die zugrunde liegende Array-Struktur zu wissen. Der Iterator kapselt die gesamte Logik zum Durchlaufen und hält die interne Darstellung der Sammlung vor dem Client-Code verborgen!

Probier es selbst

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: Erstelle eine Playlist mit Kapazität für 10 Songs
        
        // TODO: Analysiere die Eingabe (kommagetrennt) und füge jeden Songtitel zur Playlist hinzu
        
        // TODO: Erhalte einen Iterator von der Playlist mit createIterator()
        
        // TODO: Verwende den Iterator, um alle Songs zu durchlaufen
        // Für jeden Song, verpacke ihn in ein Song-Objekt und gib ihn aus
        
        // TODO: Print "Playlist complete!" after iterating through all songs
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Java-Compiler