Frage

Ich habe gerade erfahren, wie die Java Collections Framework implementiert Datenstrukturen in verkettete Listen. in einer Datenstruktur wie eine Liste von dem, was ich verstehe, Iterators ist ein Weg durch die Elemente zu durchqueren. Warum ist diese Schnittstelle verwendet? Warum sind die Methoden hasNext(), next() und remove() nicht direkt codiert auf die Datenstruktur Implementierung selbst?

Von der Java-Website: Link-Text

  

public interface Iterator

Ein   iterator eine Sammlung über. Iterator   tritt an die Stelle der Aufzählung in der   Java Collections Framework. Iteratoren   unterscheiden sich von Aufzählungen auf zwei Arten:

     

  • Iteratoren ermöglichen es dem Anrufer zu entfernen   Elemente aus dem zugrundeliegenden   Sammlung während der Iteration mit   gut definierte Semantik.
  • Methodennamen   verbessert.
Diese Schnittstelle ist   ein Mitglied der Java Collections   Framework.

Ich habe versucht, um googeln und kann nicht scheinen, eine definitive Antwort zu finden. Kann jemand etwas Licht auf, warum Sun entschied sich, sie zu benutzen? Ist es wegen der besseren Design? Erhöhte Sicherheit? Gut OO Praxis?

Jede Hilfe wird sehr geschätzt. Danke.

War es hilfreich?

Lösung

  

Warum ist diese Schnittstelle verwendet?

Weil es die grundlegenden Operationen unterstützt, die ein Client-Programmierer iterieren jede Art von Sammlung erlauben würden (man beachte: nicht unbedingt ein Collection im Object Sinne).

  

Warum sind die Methoden, ... nicht direkt   codiert der Datenstruktur   Implementierung selbst?

Sie sind, sie markiert nur Privat, so dass Sie nicht in sie und Dreck mit ihnen erreichen kann. Genauer gesagt:

  • Sie können eine Iterator implementieren oder Unterklasse, so dass sie etwas tut, der Standard nicht tun, ohne das eigentliche Objekt zu verändern, die es iteriert.
  • Objekte, die überfahren werden können brauchen nicht ihre Schnittstellen mit Traversal Methoden vollgestopft haben, insbesondere keine hochspezialisierten Methoden.
  • Sie können Iterators zu jedoch viele Kunden auszuhändigen Sie es wünschen, und jeder Kunde kann in ihrer eigenen Zeit, in ihrem eigenen Tempo durchqueren.
  • Java Iterators aus dem Paket java.util insbesondere eine Ausnahme, wenn die Speicher werfen, die sie sichert geändert wird, während Sie noch ein Iterator heraus haben. Diese Ausnahme lässt Sie wissen, dass die Iterator jetzt ungültige Objekte zurückkehren kann.

Für einfache Programme, nichts davon scheint wohl die Mühe wert. Die Art der Komplexität, die sie nützlich kommen auf dich schnell macht, though.

Andere Tipps

Sie fragen: "Warum die Methoden hasNext sind (), next () und remove () nicht direkt codiert auf die Datenstruktur Implementierung selbst?"

.

Das Java Collections Framework wählt die Iterator-Schnittstelle als externalisiert der Sammlung selbst zu definieren. Da normalerweise jede Java Sammlung des Iterable-Schnittstelle implementiert, wird ein Java-Programm iterator ruft seinen eigenen Iterator zu schaffen, so dass es in einer Schleife verwendet werden kann. Wie andere haben darauf hingewiesen, Java 5 ermöglicht es uns, Nutzung des Iterators zu richten, mit einem für-jeder Schleife.

Externalisierende den Iterator zu seiner Sammlung ermöglicht es dem Client zu steuern, wie man eine Auflistung durchläuft. Ein Anwendungsfall, die ich denken kann, wo dies sinnvoll ist, wenn man eine eine unbegrenzte Sammlung hat wie alle Web-Seiten im Internet zu indizieren.

In dem klassischen GoF Buch, der Kontrast zwischen internen und externen Iteratoren ist ganz klar dargelegt werden.

  

Ein grundsätzliches Problem ist zu entscheiden, welche Partei die Anlage Regler Iteration des Iterator oder den Client, den den Iterator verwendet. Wenn der Client die Iteration steuert, wird der Iterator ein externer Iterator genannt wird, und wenn der Iterator sie steuert, ist der Iterator ein interner Iterator. Kunden, die einen externen Iterator verwenden, müssen die Traversal vorrücken und fordern Sie das nächste Element explizit von dem Iterator. Im Gegensatz dazu reicht der Kunde einen internen Iterator eine Operation durchzuführen, und der Iterator gilt, dass der Betrieb auf jedes Element ....

     

Externe Iteratoren sind flexibler als interne Iteratoren. Es ist einfach, zwei Sammlungen für die Gleichstellung mit einem externen Iterator zu vergleichen, zum Beispiel, aber es ist praktisch unmöglich, mit internen Iteratoren ... Aber auf der anderen Seite, interne Iteratoren sind einfacher zu bedienen, weil sie die Iterationslogik für Sie definieren.

Für ein Beispiel dafür, wie interne Iteratoren arbeiten, finden Rubys Enumerable API, die interne Iterationsverfahren wie each hat. In Ruby ist die Idee, einen Code-Block passieren (das heißt ein Verschluss) zu einem internen Iterator so dass eine Sammlung Pflege der eigenen Iteration erfolgen kann.

Es ist wichtig, die Sammlung zu halten abgesehen von dem Zeiger. der Iterator weist an einer bestimmten Stelle in einer Sammlung, und somit ist kein integraler Bestandteil der Sammlung. auf diese Weise, für eine Instanz, können Sie mehrere Iteratoren über die gleiche Sammlung verwenden.

der Abwärtsseite dieser seperation ist, dass der Iterator auf Änderungen an der Sammlung aus nicht bewusst ist es iteriert auf. so kann man nicht die Struktur der Sammlung ändern und erwarten, dass der Iterator fortzusetzen es ist Arbeit ohne „Beschwerden“.

die Iterator Schnittstelle verwenden, kann jede Klasse, die seine Methoden implementiert als Iteratoren zu handeln. Die Vorstellung einer Schnittstelle in Java ist zu haben, in einer Art und Weise, eine vertragliche Verpflichtung, bestimmte Funktionalitäten in einer Klasse zur Verfügung zu stellen, die die Schnittstelle implements, in eine Weise zu handeln, die durch die Schnittstelle erforderlich ist. Da die vertraglichen Verpflichtungen müssen erfüllt sein, um eine gültige Klasse, andere Klassen zu sein, die die Klasse sehen implements die Schnittstelle und damit zu wissen, versichert, dass die Klasse diese bestimmten Funktionalitäten hat.

In diesem Beispiel, anstatt die Methoden zu implementieren (hasNext(), next(), remove()) in der LinkedList Klasse selbst wird die LinkedList Klasse erklärt, dass er die implements Schnittstelle Iterator, damit andere wissen, dass der LinkedList als Iterator verwendet werden kann. Im Gegenzug wird die LinkedList Klasse die Methoden von der Iterator Schnittstelle (wie hasNext()) implementieren, so dass es wie ein Iterator funktionieren.

Mit anderen Worten, eine Schnittstelle implementiert, ist ein objektorientierte Programmierung Begriff andere wissen, dass eine bestimmte Klasse hat, was es braucht, was es vorgibt zu sein.

Dieser Begriff wird erreicht, indem Methoden erzwungen, die von einer Klasse implementiert werden müssen, die die Schnittstelle implementiert. Dies stellt sicher, dass andere Klassen, die die Klasse verwenden möchten, die die Iterator Schnittstelle implementiert, die es in der Tat Methoden, die Iteratoren sollten, wie hasNext() haben.

Außerdem sollte beachtet werden, dass, da Java keine Mehrfachvererbung hat, kann die Verwendung von Schnittstelle, die Funktion zu emulieren verwendet werden. Durch mehrere Schnittstellen Implementierung kann man eine Klasse, die eine Unterklasse ist es, einige Funktionen erben, aber auch „erben“ die Eigenschaften eines anderen durch eine Schnittstelle zu implementieren. Ein Beispiel wäre, wenn ich eine Unterklasse der LinkedList Klasse namens ReversibleLinkedList haben will, die in umgekehrter Reihenfolge durchlaufen könnte, kann ich eine Schnittstelle namens ReverseIterator erstellen und durchzusetzen, dass es eine previous() Methode zur Verfügung stellen. Da die LinkedList bereits Iterator implementiert, würde die neue reversible Liste umgesetzt hat sowohl das Iterator und ReverseIterator Schnittstellen.

Sie können mehr über Schnittstellen von Was ist eine Schnittstelle? aus den Java-Tutorial von Sun.

Mehrere Instanzen eines interator können gleichzeitig verwendet werden. Sprechen Sie sie als lokale Cursor für die zugrunde liegenden Daten.

BTW: begünstigende Schnittstellen über konkrete Implementierungen verliert Kopplung

Achten Sie auf das Iterator-Entwurfsmuster, und hier: http://en.wikipedia.org/wiki / Iterator

Weil du über etwas sein iterieren kann, die nicht eine Datenstruktur ist. Lassen Sie uns sagen, dass ich eine vernetzte Anwendung, die Ergebnisse von einem Server zieht. Ich kann einen Iterator Wrapper um diese Ergebnisse zurück und streamen sie über jeden Standard-Code, der ein Iterator-Objekt akzeptiert.

Denken Sie daran, als ein wesentlicher Bestandteil eines guten MVC-Design. Die Daten haben aus der Modell (das heißt Datenstruktur) auf die Ansicht irgendwie zu bekommen. Mit Hilfe eines Iterator als ein Vermittler stellt sicher, dass die Umsetzung des Modells nie ausgesetzt ist. Sie könnten eine LinkedList im Speicher werden zu halten, Informationen aus einem Entschlüsselungsalgorithmus Ziehen oder JDBC-Anrufe wickeln. Es ist einfach nicht zu der Ansicht nichts, denn der Blick nur über die Iterator-Schnittstelle kümmert.

Ein interessantes Papier der Vor-und Nachteile der Verwendung von Iteratoren Diskussion:

http://www.sei.cmu.edu /pacc/CBSE5/Sridhar-cbse5-final.pdf

Ich denke, es ist nur gut OO Praxis. Sie können Code haben, der mit allen Arten von Iteratoren beschäftigt, und auch geben Ihnen die Möglichkeit, Ihre eigenen Datenstrukturen zu erstellen oder einfach nur generische Klassen, die den Iterator-Schnittstelle implementieren. Sie müssen sich keine Sorgen darüber, welche Art von Implementierung dahinter ist.

Just M2C, wenn Sie nicht bewusst waren: der Iterator-Schnittstelle vermeiden kann in Situationen direkt mit denen die for-each Schleife ausreicht.

Schließlich weil Iterator erfasst eine Steuer Abstraktion, die auf eine große Anzahl von Datenstrukturen anwendbar ist. Wenn Sie auf Ihrer Kategorie Theorie fu sind, können Sie Ihren Geist dieses Papier geblasen haben: die Essenz des Iterator-Muster .

Nun, es scheint, als ob der erste Aufzählungspunkt ermöglicht Multi-Threading (oder Single-Threaded, wenn Sie vermasseln) Anwendungen nicht die Sammlung für Concurrency Verletzungen sperren zu müssen. In .NET zum Beispiel können Sie nicht aufzählen und eine Sammlung (oder Liste oder jede IEnumerable) zur gleichen Zeit ohne Sperren oder erben von IEnumerable und übergeordneten Methoden ändern (wir Ausnahmen zu bekommen).

Iterator fügt einfach einen gemeinsamen Weg, um eine Sammlung von Gegenständen des Gehens über. Eines der netten Features ist die i.remove (), in dem Sie Elemente aus der Liste entfernen, die Sie über iterieren. Wenn Sie gerade versucht, Elemente aus einer Liste zu entfernen, normalerweise wäre es seltsam Auswirkungen hat oder werfen und Ausnahme.

Die Schnittstelle ist wie ein Vertrag für alle Dinge, die sie implementieren. Sie sind im Grunde sagen .. alles, was ein Iterator implementiert ist garantiert, diese Methoden zu haben, die die gleiche Art und Weise verhalten. Sie können es auch um Iteratortypen passieren verwenden, wenn das alles ist, Sie mit in Ihrem Code über den Umgang kümmern. (Man könnte es egal, welche Art von Liste ist .. Sie wollen einfach nur einen Iterator übergeben) Sie können diese Methoden alle unabhängig voneinander in den Sammlungen setzen konnte, aber Sie werden garantiert nicht, dass sie das gleiche verhalten oder dass sie sogar den gleichen Namen und Unterschriften.

Iteratoren sind eine der vielen Design-Patterns in Java. Design-Muster können als günstige Bausteine, Stile, Verwendung von Code / Struktur gedacht werden.

Um mehr über das Iterator-Entwurfsmuster lesen Sie die diese Website überprüfen, die über Iterator sowie viele andere Designmuster spricht. Hier ist ein Ausschnitt aus dem Ort auf Iterator: http://www.patterndepot.com/ Put / 8 / Behavioral.html

  

Der Iterator ist eine der einfachsten   und am häufigsten von der Konstruktion verwendet   Muster. Das Iterator Muster erlaubt   Sie durch eine Liste zu verschieben oder   Sammeln von Daten unter Verwendung eines Standard   Schnittstelle ohne die kennen   Details der internen   Darstellungen dieser Daten. Im   Zusätzlich können Sie auch spezielle definieren   Iteratoren, die einige besondere ausführen   Verarbeitung und Rückkehr nur angegeben   Elemente der Datensammlung.

Iteratoren kann gegen jede Art von Sammlung verwendet werden. Sie ermöglichen es, einen Algorithmus gegen eine Sammlung von Gegenständen zu definieren, unabhängig von der zugrunde liegenden Implementierung. Dies bedeutet, dass Sie eine Liste bearbeiten können, Set, String, Datei, Array, etc.

In zehn Jahre jetzt können Sie Ihre Liste Implementierung zu einer besseren Umsetzung und der Algorithmus noch nahtlos dagegen laufen ändern.

Iterator ist nützlich, wenn Sie mit Sammlungen in Java zu tun.

Mit for-each Schleife (Java1.5) zur Iteration über eine Sammlung oder ein Array oder eine Liste.

Die java.util.Iterator Schnittstelle ist in der Java Collections Framework verwendet Modifikation der Sammlung zu ermöglichen, während noch durchlaufen. Wenn Sie iterieren wollen einfach nur sauber eine ganze Kollektion, verwenden Sie einen for-each stattdessen aber ein Kopf von Iteratoren ist die Funktionalität, die Sie erhalten: eine optionale remove () Betrieb, und noch besser für die Liste Iterator-Schnittstelle, die Angebote hinzufügen () und set () zu Operationen. Beide Schnittstellen ermöglichen es Ihnen, eine Sammlung iterieren und sie strukturell zugleich zu verändern. Der Versuch, eine Sammlung zu ändern, während sie durch das Iterieren mit einem for-each einen ConcurrentModificationException werfen würde, in der Regel, weil die Sammlung unerwartet geändert wird!

Werfen Sie einen Blick auf die Klasse Arraylist

Es verfügt über 2 Privatunterricht im Innern (innere Klassen) genannt Itr und ListItr

Sie implementieren Iterator und die ListIterator Schnittstellen bzw.

public class Arraylist ..... {// umschließenden Klasse

  private class Itr implements Iterator<E> {

        public E next() {
            return ArrayList.this.get(index++); //rough, not exact
        }

        //we have to use ArrayList.this.get() so the compiler will
        //know that we are referring to the methods in the 
        //enclosing ArrayList class

        public void remove() {
            ArrayList.this.remove(prevIndex);
        }

        //checks for...co mod of the list
        final void checkForComodification() {  //ListItr gets this method as well
             if (ArrayList.this.modCount != expectedModCount) { 
                 throw new ConcurrentModificationException();
             }
        }
  }

  private class ListItr extends Itr implements ListIterator<E> {
         //methods inherted....
        public void add(E e) {
            ArrayList.this.add(cursor, e);
        }

        public void set(E e) {
            ArrayList.this.set(cursor, e);
        }
  }

}

Wenn Sie die Methoden iterator () aufrufen und ListIterator (), kehren sie eine neue Instanz der private Klasse Itr oder ListItr und da diese inneren Klassen „innerhalb“ der umschließenden Arraylist-Klasse sind, können sie frei die Arraylist ändern, ohne einen ConcurrentModificationException Auslösung, wenn Sie die Liste zur gleichen Zeit (conccurently) durch Satz ändern () () hinzufügen oder entfernen () Methoden der Arraylist-Klasse.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top