Was ist der Unterschied zwischen Iterator und Iterable und wie werden sie verwendet?


195

Ich bin neu in Java und ich bin wirklich verwirrt mit Iterator und iterierbar. Kann mir jemand erklären und einige Beispiele geben?

Antworten:


199

An Iterableist eine einfache Darstellung einer Reihe von Elementen, die wiederholt werden können. Es hat keinen Iterationsstatus wie ein "aktuelles Element". Stattdessen gibt es eine Methode, die eine erzeugt Iterator.

An Iteratorist das Objekt mit dem Iterationsstatus. Hier können Sie überprüfen, ob mehr Elemente verwendet werden, hasNext()und mit zum nächsten Element (falls vorhanden) wechseln next().

Normalerweise sollte ein Iterablein der Lage sein, eine beliebige Anzahl gültiger Iterators zu erzeugen .


Wird das wichtig sein, wenn Iterablehat interaloder externalIterator oder ist es möglich, einen von ihnen zu haben?
Sakhunzai

90

Eine Implementierung von Iterableist eine, die eine Iteratorvon sich selbst bietet :

public interface Iterable<T>
{
    Iterator<T> iterator();
}

Ein Iterator ist eine einfache Methode, mit der einige Benutzer eine Sammlung von Daten ohne Zuweisungsberechtigungen durchlaufen können (obwohl sie entfernt werden können).

public interface Iterator<E>
{
    boolean hasNext();
    E next();
    void remove();
}

Siehe Javadoc .


16

Ich werde die Frage speziell zu ArrayList als Beispiel beantworten, um Ihnen das Verständnis zu erleichtern.

  1. Die iterierbare Schnittstelle zwingt ihre Unterklassen, die abstrakte Methode 'iterator ()' zu implementieren.
public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
  1. Die Iterator-Schnittstelle zwingt ihre Unterklassen, die abstrakten Methoden 'hasNext ()' und 'next ()' zu implementieren.
public interface Iterator {
  ...
  abstract boolean hasNext(); //Returns true if the iteration has more elements.
  abstract E next();          //Returns the next element in the iteration.
  ...
}
  1. ArrayList implementiert List, List erweitert Collection und Collection erweitert Iterable. Das heißt, Sie können die Beziehung wie folgt sehen

    'Iterable <- Collection <- List <- ArrayList'

. Und Iterable, Collection und List deklarieren nur die abstrakte Methode 'iterator ()' und ArrayList implementiert sie allein.

  1. Ich werde ArrayList-Quellcode mit der Methode 'iterator ()' wie folgt anzeigen, um detailliertere Informationen zu erhalten.

Die Methode 'iterator ()' gibt ein Objekt der Klasse 'Itr' zurück, das 'Iterator' implementiert.

public class ArrayList<E> ... implements List<E>, ...
{
  ...
  public Iterator<E> iterator() {
              return new Itr();
  }


  private class Itr implements Iterator<E> {
          ...

          public boolean hasNext() {
              return cursor != size;
          }
          @SuppressWarnings("unchecked")
          public E next() {
              checkForComodification();
              int i = cursor;
              if (i >= size)
                  throw new NoSuchElementException();
              Object[] elementData = ArrayList.this.elementData;
              if (i >= elementData.length)
                  throw new ConcurrentModificationException();
              cursor = i + 1;
              return (E) elementData[lastRet = i];
          }
          ...
  }
}
  1. Einige andere Methoden oder Klassen iterieren Elemente von Sammlungen wie ArrayList mithilfe von Iterator (Itr).

Hier ist ein einfaches Beispiel.

public static void main(String[] args) {

    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    list.add("f");

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

Ist es jetzt klar? :) :)


Gute Antwort .!
Kavindu Dodanduwa

Ich habe diesen Beitrag verstanden, aber was ist, wenn ich eine Methode schreiben möchte, deren Rückgabetyp Iterable<T>in diesem Szenario ist? Welche Schritte müssen wir implementieren? Bitte schlagen Sie dieses Beispiel auch vor.
Prasanna Sasne

12

Wenn eine Sammlung iterierbar ist, kann sie mit einem Iterator iteriert werden (und kann folglich in einer für jede Schleife verwendet werden). Der Iterator ist das eigentliche Objekt, das die Sammlung durchlaufen wird.


2
Zu Ihrer Information: Eine java.util.Collection implementiert immer java.util.Iterable.
Paul Draper

2
Ist es nicht java.lang.Iterable?
Ulab

Es istjava.lang.Iterable
Aldok

9

Durch die Implementierung der Iterable-Schnittstelle kann ein Objekt das Ziel der Anweisung "foreach" sein.

class SomeClass implements Iterable<String> {}

class Main 
{
  public void method()
  {
     SomeClass someClass = new SomeClass();
     .....

    for(String s : someClass) {
     //do something
    }
  }
}

Iterator ist eine Schnittstelle, die für die Iteration über Elemente implementiert ist. Iterable ist eine Schnittstelle, die Iterator bereitstellt.


1
Wenn eine Klasse Iterable implementiert, sollte sie eine Iterator () -Methode enthalten, oder ??? Korrigieren Sie mich, wenn ich falsch liege.
Chinmaya B

Ja. Es sollte die nicht implementierte Methode der Schnittstelle haben. In diesem Fall ist es Iterator.
Agent.smith

Danke für eine intelligente Antwort. Ich bin hierher gekommen, um mein Verständnis von Iterable vs Iterator zu überprüfen. Du hast es bestätigt. Alle anderen Antworten sprechen über die Struktur, was meiner Meinung nach in Ordnung ist, aber nicht die Frage beantwortet, WARUM ich eine über die andere verwenden würde.
EricGreg

Für mich ist das die beste Antwort.
Sam

Ich wollte wissen, was der Vorteil von Für jede Schleife für String s: someClass ist. Da someClass ein Java-Klassenobjekt ist und s String ref. Unter welchen Umständen sollte man mit solchen Implementierungen gehen.
Neeraj

8

Die wichtigste Überlegung ist, ob der betreffende Gegenstand mehr als einmal durchlaufen werden kann. Dies liegt daran, dass Sie eine Iterable jederzeit zurückspulen können, indem Sie iterator () erneut aufrufen. Es gibt jedoch keine Möglichkeit, einen Iterator zurückzuspulen.


Ich habe mich gefragt, warum Sammlungsklassen die Iterator-Schnittstelle nicht direkt implementieren (anstatt Iterable zu implementieren und das Iterator-Objekt zurückzugeben). Diese Antwort machte deutlich, dass es in diesem Fall nicht möglich gewesen wäre, die Sammlung mehrmals (und auch gleichzeitig von mehreren Threads) zu durchlaufen. Dies ist eine sehr wichtige Antwort.
simpleDev

2

Wie hier erklärt , wurde The " Iterable " eingeführt, um in der foreachSchleife verwendet werden zu können. Eine Klasse, die die Iterable- Schnittstelle implementiert , kann durchlaufen werden.

Iterator ist eine Klasse, die die Iteration über eine Iterable verwaltet . Es behält den Zustand bei, in dem wir uns in der aktuellen Iteration befinden, und weiß, was das nächste Element ist und wie es abgerufen werden kann.


2

Betrachten Sie ein Beispiel mit 10 Äpfeln. Wenn es Iterable implementiert, ist es so, als würde man jeden Apfel in Kästchen von 1 bis 10 setzen und einen Iterator zurückgeben, der zum Navigieren verwendet werden kann.

Durch die Implementierung des Iterators können wir jeden Apfel, Apfel in den nächsten Kisten usw. erhalten.

Durch die Implementierung von iterable kann ein Iterator durch seine Elemente navigieren, obwohl zum Navigieren ein Iterator implementiert werden muss.


1

Frage: Unterschied zwischen Iterable und Iterator?
Ans:

iterable: Es bezieht sich auf forEach-Schleifeniterator
: Is bezieht sich auf Collection

Das Zielelement der forEach-Schleife muss iterierbar sein.
Wir können Iterator verwenden, um das Objekt einzeln aus der Sammlung abzurufen

Iterable vorhanden in java.ḷang Paket
vorhanden Iterator in java.util-Paket vorhanden

Enthält nur einen Methodeniterator ()
Enthält drei Methoden hasNext (), next (), remove ()

Eingeführt in Version 1.5
Eingeführt in Version 1.2


1

Grundsätzlich sind beide sehr eng miteinander verwandt.

Betrachten Sie Iterator als eine Schnittstelle, die uns beim Durchlaufen einer Sammlung mithilfe einiger undefinierter Methoden wie hasNext (), next () und remove () hilft.

Auf der anderen Seite ist Iterable eine weitere Schnittstelle, die, wenn sie von einer Klasse implementiert wird, die Klasse zu Iterable zwingt und ein Ziel für For-Each-Konstrukte ist. Es gibt nur eine Methode namens iterator (), die von der Iterator-Schnittstelle selbst stammt.

Wenn eine Sammlung iterierbar ist, kann sie mit einem Iterator iteriert werden.

Zum Verständnis besuchen Sie diese:

ITERABLE: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Iterable.java

ITERATOR http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Iterator.java


1

Ich weiß, dass dies eine alte Frage ist, aber für jeden, der dies liest, der mit derselben Frage feststeckt und mit der ganzen Terminologie überfordert ist, ist hier eine gute, einfache Analogie, die Ihnen hilft, diese Unterscheidung zwischen Iterablen und Iteratoren zu verstehen:

Denken Sie an eine öffentliche Bibliothek. Alte Schule. Mit Papierbüchern. Ja, diese Art von Bibliothek.

Ein Regal voller Bücher wäre wie ein iterierbares. Sie können die lange Reihe von Büchern im Regal sehen. Sie wissen vielleicht nicht, wie viele, aber Sie können sehen, dass es sich um eine lange Sammlung von Büchern handelt.

Der Bibliothekar wäre wie der Iterator. Er kann jederzeit auf ein bestimmtes Buch verweisen. Er kann das Buch an der Stelle einfügen / entfernen / ändern / lesen, auf die er zeigt. Er zeigt nacheinander jedes Mal auf jedes Buch, wenn Sie "next!" zu ihm. Normalerweise würden Sie ihn also fragen: "Hat Next?", Und er wird "Ja" sagen, zu dem Sie "Weiter" sagen. und er wird auf das nächste Buch zeigen. Er weiß auch, wann er das Ende des Regals erreicht hat, so dass, wenn Sie fragen: "Hat Next?" er wird "nein" sagen.

Ich weiß, dass es ein bisschen albern ist, aber ich hoffe, das hilft.


0

Neben ColinD und Seeker Antworten.

In einfachen Worten, Iterable und Iterator sind beide Schnittstellen, die im Java Collection Framework bereitgestellt werden.

Wiederholbar

Eine Klasse muss die Iterable-Schnittstelle implementieren, wenn sie eine for-each- Schleife zum Durchlaufen ihrer Sammlung haben möchte . Die for-each-Schleife kann jedoch nur verwendet werden, um die Sammlung in Vorwärtsrichtung zu durchlaufen, und Sie können die Elemente in dieser Sammlung nicht ändern . Wenn Sie jedoch nur die Elementdaten lesen möchten, ist dies sehr einfach und dank des Java-Lambda-Ausdrucks häufig ein Einzeiler. Beispielsweise:

iterableElements.forEach (x -> System.out.println(x) );

Iterator

Mit dieser Schnittstelle können Sie eine Sammlung durchlaufen und deren Elemente abrufen und entfernen. Jede der Auflistungsklassen stellt eine iterator () -Methode bereit , die einen Iterator an den Anfang der Auflistung zurückgibt. Der Vorteil dieser Schnittstelle gegenüber iterierbar ist, dass Sie mit dieser Schnittstelle Elemente in einer Sammlung hinzufügen, ändern oder entfernen können . Der Zugriff auf Elemente erfordert jedoch etwas mehr Code als iterierbar. Beispielsweise:

for (Iterator i = c.iterator(); i.hasNext(); ) {
       Element e = i.next();    //Get the element
       System.out.println(e);    //access or modify the element
}

Quellen:

  1. Java Doc Iterable
  2. Java Doc Iterator

0

Iterable wurden eingeführt, um für jede Schleife in Java zu verwenden

public interface Collection<E> extends Iterable<E>  

Iteratorist eine Klasse, die die Iteration über eine verwaltet Iterable. Es behält den Zustand bei, in dem wir uns in der aktuellen Iteration befinden, und weiß, was das nächste Element ist und wie es abgerufen werden kann.


Willkommen bei SO, Sie könnten jederzeit die Tour hier machen , damit Ihre Antwort hilfreicher und sauberer wäre. In unserem Fall fragt die Frage nach einer Erklärung für die beiden Klassen, aber Ihre Antwort ist ziemlich verwirrend, anstatt die Dinge zu klären. Versuchen Sie auch, eine Referenz zu behalten, während Sie Ausschnitte aus bekannten / gültigen / zertifizierten Quellen veröffentlichen, um Ihre Antwort konkreter zu gestalten.
AntJavaDev
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.