Jaka jest różnica między iteratorem a iterowalnością i jak z nich korzystać?


196

Jestem nowy w Javie i naprawdę mylę się z iteratorem i iterowalnością. Czy ktoś może mi wyjaśnić i podać kilka przykładów?

Odpowiedzi:


201

Jest Iterableto prosta reprezentacja szeregu elementów, które można iterować. Nie ma żadnego stanu iteracji, takiego jak „bieżący element”. Zamiast tego ma jedną metodę, która tworzyIterator .

An Iteratorjest obiektem ze stanem iteracji. Pozwala sprawdzić, czy ma więcej elementów za pomocą hasNext()i przejść do następnego elementu (jeśli istnieje) za pomocą next().

Zazwyczaj Iterablepowinien być w stanie wygenerować dowolną liczbę poprawnych Iterators.


czy to będzie ważne, czy Iterablema interallub externaliterator, czy można mieć którekolwiek z nich?
sakhunzai

91

Implementacja Iterableto taka, która zapewnia Iterator:

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

Iterator to prosty sposób pozwalający niektórym przeglądać kolekcję danych bez uprawnień do przypisywania (choć z możliwością usuwania).

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

Zobacz Javadoc .


17

Odpowiem na pytanie szczególnie o ArrayList jako przykład, aby pomóc Ci lepiej zrozumieć ..

  1. Interfejs Iterable wymusza na swoich podklasach implementację metody abstrakcyjnej „iterator ()”.
public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
  1. Interfejs Iterator wymusza na swoich podklasach implementację metody abstrakcyjnej „hasNext ()” i „next ()”.
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 implementuje List, List rozszerza Kolekcję i Kolekcja rozszerza Iterable .. To znaczy, możesz zobaczyć relację jak

    „Iterable <- Collection <- List <- ArrayList”

. Iterable, Collection i List deklarują po prostu metodę abstrakcyjną „iterator ()”, a sama ArrayList ją implementuje.

  1. Pokażę kod źródłowy ArrayList za pomocą metody „iterator ()” w następujący sposób, aby uzyskać bardziej szczegółowe informacje.

Metoda „iterator ()” zwraca obiekt klasy „Itr”, który implementuje „Iterator”.

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. Niektóre inne metody lub klasy będą iterować elementy kolekcji, takie jak ArrayList, wykorzystując Iterator (Itr).

Oto prosty przykład.

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);
    }
}

Czy to jasne? :)


Świetna odpowiedź .!
Kavindu Dodanduwa

Zrozumiałem ten post, ale co jeśli chcę napisać metodę, której typ zwracany jest Iterable<T>w tym scenariuszu, jakie kroki musimy wdrożyć? Proszę również zasugerować ten przykład.
Prasanna Sasne

12

Jeśli kolekcja jest iterowalna, to można ją iterować za pomocą iteratora (i w konsekwencji można go użyć w pętli dla każdej). Iterator jest rzeczywistym obiektem, który będzie iterował przez kolekcję.


2
Do Twojej wiadomości java.util.Collection zawsze implementuje java.util.Iterable.
Paul Draper,

2
Czyż nie java.lang.Iterable?
ulab

Jestjava.lang.Iterable
aldok

9

Implementacja interfejsu Iterable pozwala obiektowi być celem instrukcji „foreach”.

class SomeClass implements Iterable<String> {}

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

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

Iterator to interfejs, który ma implementację do iteracji elementów. Iterable to interfejs zapewniający Iterator.


1
Jeśli jakakolwiek klasa implementuje Iterable, powinna mieć w sobie metodę Iterator (), prawda? Popraw mnie, jeśli się mylę.
Chinmaya B,

tak. Powinien mieć niezaimplementowaną metodę interfejsu. W tym przypadku jest to Iterator.
agent.smith

Dzięki za inteligentną odpowiedź. Przyszedłem tutaj, aby dokładnie sprawdzić moje rozumienie Iterable vs. Iterator. Potwierdziłeś to. Wszystkie pozostałe odpowiedzi mówią o strukturze, co, jak sądzę, jest w porządku, ale nie odpowiada na pytanie, DLACZEGO użyłbym jednej nad drugą.
EricGreg,

Dla mnie to najlepsza odpowiedź.
Sam

Chciałem wiedzieć, jaka jest korzyść dla każdej pętli dla String s: someClass. Ponieważ someClass jest obiektem klasy java is ref. W jakich okolicznościach należy stosować tego rodzaju wdrożenia.
Neeraj,

8

Najważniejszą kwestią jest to, czy dany przedmiot powinien być dostępny więcej niż jeden raz. Wynika to z faktu, że zawsze można przewinąć Iterator, wywołując ponownie iterator (), ale nie ma sposobu na przewinięcie Iteratora.


Zastanawiałem się, dlaczego klasy kolekcji nie implementują interfejsu Iterator bezpośrednio (zamiast implementacji Iterable i zwracania obiektu Iterator). Ta odpowiedź wyjaśniła, że ​​- w takim przypadku nie byłoby możliwe przechodzenie przez kolekcję wiele razy (a także jednocześnie przez wiele wątków). To bardzo ważna odpowiedź.
simpleDev

2

Jak wyjaśniono tutaj , „ Iterable ” został wprowadzony, aby móc używać go w foreachpętli. Klasa implementująca interfejs Iterable może być iterowana.

Iterator jest klasa, która zarządza iteracji nad iterable . Utrzymuje stan, w którym znajdujemy się w bieżącej iteracji, i wie, jaki jest następny element i jak go uzyskać.


2

Rozważ przykład z 10 jabłkami. Kiedy implementuje Iterable, przypomina to umieszczenie każdego jabłka w pudełkach od 1 do 10 i zwrócenie iteratora, którego można użyć do nawigacji.

Wdrażając iterator, możemy uzyskać dowolne jabłko, jabłko w kolejnych polach itp.

Tak więc implementacja iterable daje iteratorowi nawigację po jego elementach, chociaż aby nawigować, iterator musi zostać zaimplementowany.


1

Pytanie: Różnica między Iterable i Iterator?
Odp .:

iterable: Jest powiązany z
iteratorem pętli forEach : Jest powiązany z kolekcją

Element docelowy pętli forEach powinien być powtarzalny.
Możemy użyć Iteratora, aby pobrać obiekt jeden po drugim z Kolekcji

Iterable obecny w pakiecie java.ḷang
Iterator obecny w pakiecie java.util

Zawiera tylko jedną metodę iteratora ()
Zawiera trzy metody hasNext (), next (), remove ()

Wprowadzono w wersji 1.5
Wprowadzono w wersji 1.2


1

Zasadniczo oba są ze sobą ściśle powiązane.

Rozważmy Iterator jako interfejs, który pomaga nam przechodzić przez kolekcję za pomocą niektórych niezdefiniowanych metod, takich jak hasNext (), next () i remove ()

Z drugiej strony, Iterable to kolejny interfejs, który, jeśli jest zaimplementowany przez klasę, wymusza klasę Iterable i jest celem dla konstrukcji For-Each. Ma tylko jedną metodę o nazwie iterator (), która pochodzi z samego interfejsu Iterator.

Gdy kolekcja jest iterowalna, można ją iterować za pomocą iteratora.

Dla zrozumienia odwiedź:

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

Wiem, że to stare pytanie, ale dla każdego, kto czyta to pytanie, które utknęło z tym samym pytaniem i które może być przytłoczone całą terminologią, oto dobra, prosta analogia, która pomoże ci zrozumieć to rozróżnienie między iteratorami a iteratorami:

Pomyśl o bibliotece publicznej. Stara szkoła. Z papierowymi książkami. Tak, taka biblioteka.

Półka pełna książek przypominałaby iterację. Na półce widać długą linię książek. Możesz nie wiedzieć ile, ale możesz zobaczyć, że jest to długi zbiór książek.

Bibliotekarz byłby jak iterator. Może wskazać konkretną książkę w dowolnym momencie. Może wstawiać / usuwać / modyfikować / czytać książkę w miejscu, w którym wskazuje. Wskazuje kolejno każdą książkę za każdym razem, gdy krzyczysz „dalej!” do niego. Zwykle pytasz go: „ma Dalej?”, A on powie „tak”, na co mówisz „dalej!”. i wskaże następną książkę. Wie również, kiedy dotarł do końca półki, więc kiedy zapytasz: „ma Dalej?” powie „nie”.

Wiem, że to trochę głupie, ale mam nadzieję, że to pomoże.


0

Oprócz odpowiedzi ColinD i Seeker .

W prostych słowach Iterable i Iterator to interfejsy dostarczone w Java's Collection Framework.

Iterowalny

Klasa musi zaimplementować interfejs Iterable, jeśli chce mieć pętlę „ for-each” w celu iteracji swojej kolekcji. Jednak for-each pętli może być używany tylko do cyklu poprzez gromadzenie w kierunku do przodu i nie będzie mógł modyfikować elementy w tej kolekcji . Ale jeśli wszystko, czego chcesz, to odczyt danych elementów, to jest to bardzo proste, a dzięki wyrażeniu lambda Java jest to często jedna linijka. Na przykład:

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

Iterator

Ten interfejs umożliwia iterację kolekcji, uzyskiwanie i usuwanie jej elementów. Każda z klas kolekcji udostępnia metodę iteratora () , która zwraca iterator na początek kolekcji. Zaletą tego interfejsu nad iteracją jest to, że za pomocą tego interfejsu można dodawać, modyfikować lub usuwać elementy w kolekcji . Jednak dostęp do elementów wymaga nieco więcej kodu niż iteracji. Na przykład:

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

Źródła:

  1. Java Doc Iterable
  2. Java Doc Iterator

0

Iterable zostały wprowadzone do użycia dla każdej pętli w java

public interface Collection<E> extends Iterable<E>  

Iteratorto klasa zarządzająca iteracją nad Iterable. Utrzymuje stan, w którym znajdujemy się w bieżącej iteracji, i wie, jaki jest następny element i jak go uzyskać.


Witamy w SO, zawsze możesz wziąć tu wycieczkę , aby Twoja odpowiedź była bardziej pomocna i czysta. W naszym przypadku pytanie wymaga wyjaśnienia na temat dwóch klas, ale twoja odpowiedź jest dość myląca zamiast wyjaśnienia. Postaraj się również zachować referencję, publikując fragmenty ze znanych / ważnych / certyfikowanych źródeł, aby Twoja odpowiedź była bardziej konkretna.
AntJavaDev,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.