Почему объект, реализующий Iterable, ведет себя как множество?

286
21 мая 2017, 21:40

У меня есть код, в котором экземпляр класса, реализующего интерфейс Iterable, помещен в цикл foreach, и это не только не вызывает у компилятора возражений, но оно еще и работает. Но как - я не понимаю.

Код

class ArrayIterator implements Iterator {
    private int index = 0;
    private final int[] values;
    ArrayIterator(int[] values) {
        this.values = values;
    }
    public boolean hasNext() {
        return index < values.length;
    }
    public Object next() {
        return values[index++];
    }
    @Override
    public void remove() {
    }
}
class ForEachArray implements Iterable {
    private final int[] values;
    ForEachArray(final int[] values) {
        this.values = values;
    }
    public Iterator iterator() {
        return new ArrayIterator(this.values);
    }
}
class Main {
    public static void main(String[] args) {
        ForEachArray forEach = new ForEachArray(new int[]{1, 2, 3, 4, 5});
        for (Object value : forEach) {
            System.out.println(value);
        }
    }
}

Выводит:

1
2
3
4
5

Почему экземпляр класса, который не является ни массивом, ни коллекцией, попав в цикл на место множества, работает как множество? Что происходит в потоке выполнения? Как получается, что цикл for умудряется вызвать сначала метод iterator() у ForEachArray (ну это еще ладно: на то он и Iterable), а потом еще и hasNext() и next() у ArrayIterator? Вот что непонятно.

Answer 1

For-Each цикл

for (Object value : forEach) {
    System.out.println(value);
}

работает таким образом:

for (Iterator i = forEach.iterator(); i.hasNext();)
{
    Object value = i.next();
    System.out.println(value);
}

Метод iterator класса ForEachArray у вас возвращает ArrayIterator. Соответственно, методы hasNext и next вызываются как раз у ArrayIterator.

READ ALSO
Быстрое преобразование Фурье. Частоты

Быстрое преобразование Фурье. Частоты

ЗдравствуйтеЗаинтересовался реализацией выделением нот и распознаванием сигналов исходя из нот

320
Ошибка при остановке Tomcat 8 QuarzListener Java EE

Ошибка при остановке Tomcat 8 QuarzListener Java EE

Поставил QuartzСоздал слушателя, "работу"

359
Как создать &ldquo;древовидные&rdquo; массивы в JSON?

Как создать “древовидные” массивы в JSON?

Я понимаю как "распарсить" строку json в которой есть древовидная структура, но не могу понять, как создать дополнительные массивы в определенной...

283
Удаление комментариев из javа-программы

Удаление комментариев из javа-программы

Из текста java-программы удалить комментарии вида // и /*Новый текст записать в тот же файл

408