Чим відрізняється ітератор від ітерабельного та як ними користуватися?


197

Я новачок в Java, і я справді плутаюся з ітератором і ітерабельним. Хтось може мені пояснити і навести кілька прикладів?

Відповіді:


201

Це Iterableпросте зображення ряду елементів, які можна повторити. У ньому немає жодного стану ітерації, наприклад "поточний елемент". Натомість у нього є один метод, який виробляє Iterator.

А 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 реалізує список, список розширює колекцію, а колекція розширює Iterable .. Тобто, ви могли бачити відносини, як

    'Iterable <- Колекція <- Список <- 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);
    }
}

Тепер це зрозуміло? :)


Чудова відповідь!
Kavindu Dodanduwa

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

12

Якщо колекція є ітерабельною, то її можна повторити за допомогою ітератора (і, отже, може бути використаний у а для кожного циклу.


2
FYI a 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 () ??? Виправте мене, якщо я помиляюся.
Chinmaya B

так. Він повинен мати непроведений метод інтерфейсу. У цьому випадку це Ітератор.
agent.smith

Дякую за розумну відповідь. Я прийшов сюди, щоб ще раз перевірити своє розуміння Iterable vs Iterator. Ви це підтвердили. Усі інші відповіді говорять про структуру, яка, напевно, гарна, але не відповідає на питання ЧОМУ я б використовував одну над іншою.
EricGreg

Для мене це найкраща відповідь.
Сем

Мені хотілося знати, яка вигода для кожного циклу для String s: someClass. Оскільки someClass є об’єктом класу java, а s String ref. За яких обставин треба йти з подібними реалізаціями.
Neeraj

8

Найважливіше врахування, чи слід переглядати цей предмет не один раз. Це тому, що ви завжди можете перемотати Iterable, зателефонувавши до iterator (), але немає можливості перемотати Iterator.


Мені було цікаво, чому класи колекції не реалізують інтерфейс Iterator безпосередньо (замість реалізації Iterable та повернення Iterator-об’єкта). Ця відповідь дала зрозуміти, що - у такому випадку неможливо було б пройти колекцію кілька разів (а також одночасно декількома потоками). Це дуже важлива відповідь.
simpleDev

2

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

Ітератор - це клас, який управляє ітерацією над Iterable . Він підтримує стан, де ми перебуваємо в поточній ітерації, і знає, що таке наступний елемент і як його отримати.


2

Розглянемо приклад з 10 яблуками. Коли він реалізує Iterable, це схоже на те, щоб помістити кожне яблуко в поля від 1 до 10 і повернути ітератор, який можна використовувати для навігації.

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

Таким чином, реалізація iterable дає ітератору орієнтуватися по його елементам, хоча для навігації ітератор повинен бути реалізований.


1

Питання: Різниця між Iterable та Iterator?
Відповідь:

iterable: Це пов’язано з
ітератором циклу forEach: Є пов'язане з колекцією

Цільовий елемент циклу forEach має бути ітерабельним.
Ми можемо використовувати Iterator, щоб отримати об'єкт по одному з колекції

Ітерабельний подарунок у пакеті java.ḷang
Ітератор присутній у пакеті java.util

Містить лише один ітератор методу ()
Містить три методи hasNext (), next (), remove ()

Введено у версії 1.5.
Введено у версії 1.2


1

В основному обидва вони дуже тісно пов'язані один з одним.

Розглянемо Iterator як інтерфейс, який допомагає нам проходити колекцію за допомогою деяких невизначених методів, таких як hasNext (), next () та delete ()

З іншого боку, Iterable - це інший інтерфейс, який, якщо його реалізує клас, примушує клас бути Iterable і є цільовою конструкцією для For-Every. Він має лише один метод з назвою iterator (), який походить від самого інтерфейсу Iterator.

Коли колекція є ітерабельною, її можна повторити за допомогою ітератора.

Для розуміння відвідайте ці:

ІТЕРАБІЛЬНО: 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 Collection Collection.

Ітерабельний

Клас повинен реалізувати інтерфейс Iterable, якщо він хоче мати цикл для кожного перебору для його колекції. Однак цикл для кожного циклу може використовуватися лише для переходу колекції у напрямку вперед, і ви не зможете змінювати елементи цієї колекції . Але, якщо ви хочете лише прочитати дані елементів, то це дуже просто, і завдяки вираженню лямбда 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.