В чем разница между итератором и итерируемым и как их использовать?


197

Я новичок в Java, и я действительно запутался с итератором и повторяем. Может кто-нибудь объяснить мне и привести несколько примеров?

Ответы:


201

An Iterableпредставляет собой простое представление серии элементов, которые могут быть повторены. У него нет состояния итерации, такого как «текущий элемент». Вместо этого у него есть один метод, который производит Iterator.

An Iterator- объект с состоянием итерации. Он позволяет вам проверить, есть ли в нем больше элементов, hasNext()и перейти к следующему элементу (если есть), используя next().

Как правило, Iterableдолжно быть в состоянии произвести любое количество действительных Iterators.


будет ли это иметь значение, если Iterableесть interalили externalитератор или возможно иметь любой из них?
Сахунзай

91

Реализация Iterable- это та, которая обеспечивает Iteratorсебя:

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

Итератор - это простой способ позволить некоторым циклически проходить по коллекции данных без привилегий присвоения (хотя и с возможностью удаления).

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

Смотри Javadoc .


17

Я отвечу на вопрос, особенно о ArrayList в качестве примера, чтобы помочь вам лучше понять ..

  1. Итерируемый интерфейс заставляет его подклассы реализовывать абстрактный метод iterator ().
public interface Iterable {
  ...
  abstract Iterator<T> iterator(); //Returns an 'Iterator'(not iterator) over elements of type T.
  ...
}
  1. Интерфейс итератора заставляет его подклассы реализовывать абстрактный метод hasNext () и 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 реализует List, List расширяет Collection и Collection расширяет Iterable .. То есть, вы можете видеть отношения как

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

, И Iterable, Collection и List просто объявляют абстрактный метод 'iterator ()', и только ArrayList реализует его.

  1. Я собираюсь показать исходный код ArrayList с методом 'iterator ()' следующим образом для получения более подробной информации.

Метод iterator () возвращает объект класса Itr, который реализует 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. Некоторые другие методы или классы будут повторять элементы коллекций, такие как ArrayList, используя Iterator (Itr).

Вот простой пример.

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

Теперь понятно? :)


Отличный ответ.
Кавинду Додандува

Я понял этот пост, но что, если я захочу написать метод, тип возвращаемого значения которого Iterable<T>в этом сценарии, какие шаги нам нужно реализовать? Пожалуйста, предложите этот пример также.
Прасанна Сасне

12

Если коллекция является итеративной, то она может повторяться с использованием итератора (и, следовательно, может использоваться в каждом цикле.) Итератор - это реальный объект, который будет выполнять итерацию по коллекции.


2
К вашему сведению java.util.Collection всегда реализует java.util.Iterable.
Пол Дрейпер

2
Это не java.lang.Iterable ?
Ulab

Этоjava.lang.Iterable
Алдок,

9

Реализация интерфейса Iterable позволяет объекту быть целью оператора foreach.

class SomeClass implements Iterable<String> {}

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

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

Iterator - это интерфейс, который имеет реализацию для перебора элементов. Iterable - это интерфейс, который предоставляет Iterator.


1
Если какой-либо класс реализует Iterable, у него должен быть метод Iterator (), верно? Поправь меня, если я ошибаюсь.
Чинмайя Б

да. У него должен быть не реализованный метод интерфейса. В данном случае это итератор.
agent.smith

Спасибо за разумный ответ. Я пришел сюда, чтобы проверить мое понимание Iterable против Iterator. Вы подтвердили это. Все остальные ответы говорят о структуре, что, я думаю, хорошо, но не отвечает на вопрос, ПОЧЕМУ я бы использовал один над другим.
EricGreg

Для меня это лучший ответ.
Сэм

Я хотел бы знать, что является преимуществом для каждого цикла для String s: someClass. Так как someClass является объектом класса java и s String ref. При каких обстоятельствах следует идти с такими реализациями.
Neeraj

8

Наиболее важным соображением является то, должен ли рассматриваемый элемент быть в состоянии пройти более одного раза. Это потому, что вы всегда можете перемотать Iterable с помощью повторного вызова iterator (), но нет способа перемотать Iterator.


Мне было интересно, почему классы коллекций не реализуют интерфейс Iterator напрямую (вместо реализации Iterable и возврата объекта Iterator). Этот ответ дал понять, что - в этом случае не было бы возможности проходить сбор несколько раз (а также одновременно несколькими потоками). Это очень важный ответ.
simpleDev

2

Как объяснено здесь , « Iterable » был введен для возможности использования в foreachцикле. Класс, реализующий интерфейс Iterable, может быть перебран.

Iterator - это класс, который управляет итерацией над Iterable . Он поддерживает состояние, в котором мы находимся в текущей итерации, и знает, что такое следующий элемент и как его получить.


2

Рассмотрим пример с 10 яблоками. Когда он реализует Iterable, это все равно что складывать каждое яблоко в ячейки от 1 до 10 и возвращать итератор, который можно использовать для навигации.

Реализуя итератор, мы можем получить любое яблоко, яблоко в следующих коробках и т. Д.

Таким образом, реализация iterable дает итератору для навигации по его элементам, хотя для навигации необходимо реализовать итератор.


1

Вопрос: Разница между Iterable и Iterator?
Ans:

iterable: связан с
итератором цикла forEach : is связан с Collection

Целевой элемент цикла forEach должен быть итеративным.
Мы можем использовать Iterator, чтобы получить объект один за другим из коллекции.

Итеративный подарок в пакете java.ḷang
Итератор, присутствующий в пакете java.util

Содержит только один метод iterator ()
Содержит три метода hasNext (), next (), remove ()

Представлено в версии 1.5
Представлено в версии 1.2


1

По сути, оба они очень тесно связаны друг с другом.

Считайте Iterator интерфейсом, который помогает нам обходить коллекцию с помощью некоторых неопределенных методов, таких как hasNext (), next () и remove ().

С другой стороны, Iterable является еще одним интерфейсом, который, если он реализован классом, заставляет класс быть Iterable и является целью для конструкции For-Each. У него есть только один метод с именем iterator (), который происходит из самого интерфейса Iterator.

Когда коллекция является итеративной, ее можно повторять с помощью итератора.

Для понимания посетите эти:

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

ИТЕРАТОР http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Iterator.java


1

Я знаю, что это старый вопрос, но для любого, кто читает этот вопрос, кто застрял в одном и том же вопросе и может быть перегружен всей терминологией, вот хорошая, простая аналогия, которая поможет вам понять это различие между итераторами и итераторами:

Подумайте о публичной библиотеке. Старая школа. С бумажными книгами. Да, такая библиотека.

Полка с книгами была бы как бы повторяемой. Вы можете увидеть длинную очередь книг на полке. Вы можете не знать, сколько, но вы можете видеть, что это длинная коллекция книг.

Библиотекарь будет как итератор. Он может указать на конкретную книгу в любой момент времени. Он может вставить / удалить / изменить / прочитать книгу в том месте, куда он указывает. Он последовательно указывает на каждую книгу каждый раз, когда вы кричите «следующий!» Для него. Итак, вы обычно спрашиваете его: «Имеет следующий?», И он отвечает «да», на что вы говорите «следующий»! и он укажет на следующую книгу. Он также знает, когда он достиг конца полки, так что, когда вы спрашиваете: «Есть следующий?» он скажет "нет".

Я знаю, что это немного глупо, но я надеюсь, что это поможет.


0

В дополнение к ColinD и Seeker ответы.

Проще говоря, Iterable и Iterator - оба интерфейса, предоставленные в Коллекционной платформе Java.

Iterable

Класс должен реализовывать интерфейс Iterable, если он хочет иметь для каждого цикл для итерации по своей коллекции. Однако цикл for-each можно использовать только для циклического перемещения по коллекции в прямом направлении, и вы не сможете изменять элементы в этой коллекции . Но если все, что вам нужно, это прочитать данные элементов, то это очень просто, и благодаря лямбда-выражению Java это часто один лайнер. Например:

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

Итератор

Этот интерфейс позволяет перебирать коллекцию, получать и удалять ее элементы. Каждый из классов коллекции предоставляет метод iterator (), который возвращает итератор в начало коллекции. Преимущество этого интерфейса перед итеративным состоит в том, что с этим интерфейсом вы можете добавлять, изменять или удалять элементы в коллекции . Но для доступа к элементам требуется немного больше кода, чем для повторения. Например:

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

Источники:

  1. Java Doc Iterable
  2. Java Doc Iterator

0

Iterable были введены для использования в каждом цикле в Java

public interface Collection<E> extends Iterable<E>  

Iteratorэто класс, который управляет итерацией по Iterable. Он поддерживает состояние, в котором мы находимся в текущей итерации, и знает, что такое следующий элемент и как его получить.


Добро пожаловать в SO, вы всегда можете взять тур здесь , чтобы ваш ответ был более полезным и чистым. В нашем случае вопрос требует объяснения относительно двух классов, но ваш ответ довольно запутанный, а не проясняет ситуацию. Также постарайтесь сохранить ссылку при публикации фрагментов из известных / действительных / сертифицированных источников, чтобы сделать ваш ответ более конкретным.
AntJavaDev
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.