Что такое итератор?android-38

Итератор — это поведенческий паттерн проектирования и одновременно интерфейс в Java/Kotlin, который предоставляет стандартный способ последовательного доступа к элементам коллекции без раскрытия её внутренней структуры.

1. Основная концепция

Итератор реализует принцип единственной ответственности:

  • Коллекция отвечает за хранение данных
  • Итератор отвечает за обход этих данных
public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() { ... }
}

2. Ключевые особенности

Преимущества использования:

  • Унифицированный доступ к разным типам коллекций
  • Безопасность - защита от модификации коллекции во время итерации
  • Ленивое вычисление - элементы получаются по мере необходимости

В Android-разработке:

  • Используется во всех стандартных коллекциях (ArrayList, HashSet и др.)
  • Особенно важен для работы с большими наборами данных (например, из Room Database)

3. Примеры использования

Базовый пример в Java:

List<String> androidVersions = Arrays.asList("Pie", "Q", "R");
Iterator<String> it = androidVersions.iterator();

while(it.hasNext()) {
    String version = it.next();
    Log.d("TAG", version);
}

Современный Kotlin подход:

val androidVersions = listOf("Pie", "Q", "R")
val iterator = androidVersions.iterator()

while(iterator.hasNext()) {
    val version = iterator.next()
    println(version)
}

4. Разновидности итераторов

1. ListIterator:

  • Расширяет Iterator возможностью обхода в обе стороны
ListIterator<String> listIt = androidVersions.listIterator();
listIt.previous(); // Возвращает предыдущий элемент

2. MutableIterator :

  • Добавляет функцию удаления элементов
val mutableIterator = mutableListOf(1, 2, 3).iterator()
mutableIterator.remove() // Удаляет текущий элемент

5. Внутренняя реализация

Типичная реализация итератора для ArrayList:

public Iterator<E> iterator() {
    return new Itr(); // Внутренний класс
}

private class Itr implements Iterator<E> {
    int cursor;       // Текущая позиция
    int lastRet = -1; // Последний возвращенный индекс

    public boolean hasNext() {
        return cursor != size;
    }

    public E next() {
        checkForComodification();
        int i = cursor;
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }
}

6. Опасности и лучшие практики

ConcurrentModificationException

Возникает при изменении коллекции во время итерации:

val list = mutableListOf(1, 2, 3)
val iter = list.iterator()
while(iter.hasNext()) {
    val item = iter.next()
    list.remove(item) // Выбросит исключение!
}

Правильное решение:

iter.remove() // Используем метод итератора

Лучшие практики в Android:

  1. Для больших коллекций используйте Iterator вместо for-each
  2. При работе с Room предпочитайте Iterator для ленивой загрузки
  3. В Kotlin чаще используйте extension-функции (forEach, map и т.д.)

Резюмируем:

Итератор — это мощный инструмент для безопасного и эффективного обхода коллекций, который предоставляет единый интерфейс работы с разными структурами данных и является фундаментальной частью Java/Kotlin Collections Framework.