Перейти к основному содержимому

Итераторы

Одним из ключевых методов интерфейса Collection является метод Iterator<E> iterator(). Он возвращает итератор - то есть объект, реализующий интерфейс Iterator.

Интерфейс Iterator имеет следующее определение:

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

Реализация интерфейса предполагает, что с помощью вызова метода next() можно получить следующий элемент. С помощью метода hasNext() можно узнать, есть ли следующий элемент, и не достигнут ли конец коллекции. И если элементы ещё имеются, то hasNext() вернет значение true. Метод hasNext() следует вызывать перед методом next(), так как при достижении конца коллекции метод next() выбрасывает исключение NoSuchElementException. И метод remove() удаляет текущий элемент, который был получен последним вызовом next().

Используем итератор для перебора коллекции ArrayList:

import java.util.*;

public class Program {
public static void main(String[] args) {
ArrayList<String> states = new ArrayList<>();
states.add("Germany");
states.add("France");
states.add("Italy");
states.add("Spain");

Iterator<String> iterator = states.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}

Интерфейс Iterator предоставляет ограниченный функционал. Гораздо больший набор методов предоставляет другой итератор - интерфейс ListIterator. Данный итератор используется классами, реализующими интерфейс List, то есть классами LinkedList, ArrayList и др.

Интерфейс ListIterator расширяет интерфейс Iterator и определяет ряд дополнительных методов:

  • void add(E obj): вставляет объект obj перед элементом, который должен быть возвращен следующим вызовом next().
  • boolean hasNext(): возвращает true, если в коллекции имеется следующий элемент, иначе возвращает false.
  • boolean hasPrevious(): возвращает true, если в коллекции имеется предыдущий элемент, иначе возвращает false.
  • E next(): возвращает текущий элемент и переходит к следующему, если такого нет, то генерируется исключение NoSuchElementException.
  • E previous(): возвращает текущий элемент и переходит к предыдущему, если такого нет, то генерируется исключение NoSuchElementException.
  • int nextIndex(): возвращает индекс следующего элемента. Если такого нет, то возвращается размер списка.
  • int previousIndex(): возвращает индекс предыдущего элемента. Если такого нет, то возвращается число -1.
  • void remove(): удаляет текущий элемент из списка. Таким образом, этот метод должен быть вызван после методов next() или previous(), иначе будет сгенерировано исключение IllegalStateException.
  • void set(E obj): присваивает текущему элементу, выбранному вызовом методов next() или previous(), ссылку на объект obj.

Используем ListIterator:

import java.util.*;

public class Program {
public static void main(String[] args) {
ArrayList<String> states = new ArrayList<>();
states.add("Germany");
states.add("France");
states.add("Italy");
states.add("Spain");

ListIterator<String> listIterator = states.listIterator();

while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
// сейчас текущий элемент - Испания
// изменим значение этого элемента
listIterator.set("Португалия");
// пройдемся по элементам в обратном порядке
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}
}
}