Iterator — это поведенческий паттерн, который даёт возможность последовательно обходить элементы коллекции, не раскрывая её внутреннее устройство.
Простыми словами: вы проходите по элементам через «окошко» (hasNext / next), не зная — это массив, дерево или база данных за ним.
▪️ Пример:
Пагинация по результатам из БД: клиент обходит элементы как обычную коллекцию, а итератор незаметно подгружает следующую страницу.
class PaginatedIterator<T> implements Iterator<T> {
private final Function<Integer, List<T>> pageFetcher;
private final int pageSize;
private List<T> currentPage;
private int pageIndex = 0;
private int itemIndex = 0;
public PaginatedIterator(Function<Integer, List<T>> pageFetcher,
int pageSize) {
this.pageFetcher = pageFetcher;
this.pageSize = pageSize;
this.currentPage = pageFetcher.apply(0);
}
public boolean hasNext() {
if (itemIndex < currentPage.size()) return true;
if (currentPage.size() < pageSize) return false; // последняя страница
// Подгружаем следующую страницу
pageIndex++;
currentPage = pageFetcher.apply(pageIndex);
itemIndex = 0;
return !currentPage.isEmpty();
}
public T next() {
if (!hasNext()) throw new NoSuchElementException();
return currentPage.get(itemIndex++);
}
}
// Использование — клиент не знает про пагинацию
Iterator<User> users = new PaginatedIterator<>(
page -> userRepository.findAll(PageRequest.of(page, 50)).getContent(),
50
);
while (users.hasNext()) {
User user = users.next(); // подгрузка происходит автоматически
process(user);
}▪️ Когда использовать
— Нужен единый способ обхода для разных структур данных
— Хотите скрыть сложность обхода (дерево, граф, пагинация)
— В Java: все коллекции реализуют Iterable, что позволяет for-each
▪️ Минус
Для простых коллекций — избыточен; итератор может устареть при изменении коллекции (ConcurrentModificationException).
🐸 Библиотека собеса по Java
#patterns