Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Итератор в Java
Итератор — это объект, который позволяет последовательно обходить элементы коллекции (List, Set, Queue и т.д.) без необходимости знать её внутреннюю структуру. Это реализация паттерна Iterator из GoF.
Интерфейс Iterator
public interface Iterator<E> {
boolean hasNext(); // Есть ли ещё элементы?
E next(); // Получить следующий элемент
void remove(); // Удалить текущий элемент (опционально)
}
Основное назначение
Итератор позволяет:
- Обходить элементы независимо от их хранения (массив, связный список, хеш-таблица)
- Инкапсулировать логику обхода
- Безопасно удалять элементы во время итерации
- Работать с коллекциями единообразно
Использование итератора
1. Классический способ:
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}
2. Enhanced for loop (синтаксический сахар):
Это работает, потому что List реализует Iterable.
for (String fruit : fruits) {
System.out.println(fruit);
}
// Эквивалентно:
// Iterator<String> it = fruits.iterator();
// while (it.hasNext()) {
// String fruit = it.next();
// }
3. Безопасное удаление во время итерации:
List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5));
// НЕПРАВИЛЬНО — выбросит ConcurrentModificationException
for (Integer num : numbers) {
if (num % 2 == 0) {
numbers.remove(num); // Ошибка!
}
}
// ПРАВИЛЬНО — используем iterator.remove()
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
Integer num = it.next();
if (num % 2 == 0) {
it.remove(); // Безопасное удаление
}
}
System.out.println(numbers); // [1, 3, 5]
ListIterator
ListIterator расширяет Iterator с дополнительными возможностями для работы со списками:
public interface ListIterator<E> extends Iterator<E> {
boolean hasPrevious(); // Есть ли предыдущий элемент?
E previous(); // Получить предыдущий элемент
int nextIndex(); // Индекс следующего элемента
int previousIndex(); // Индекс предыдущего элемента
void set(E e); // Заменить текущий элемент
void add(E e); // Добавить элемент перед текущей позицией
}
Пример использования ListIterator:
List<String> colors = new ArrayList<>(List.of("Red", "Green", "Blue"));
ListIterator<String> listIt = colors.listIterator();
// Перемещение туда и сюда
while (listIt.hasNext()) {
System.out.println("Forward: " + listIt.next());
}
while (listIt.hasPrevious()) {
System.out.println("Backward: " + listIt.previous());
}
// Добавление и замена
listIt = colors.listIterator();
listIt.next(); // Skip "Red"
listIt.set("Crimson"); // Replace "Green"
listIt.add("Yellow"); // Add before "Blue"
System.out.println(colors); // [Red, Crimson, Yellow, Blue]
Реализация собственного итератора
public class CustomList<E> implements Iterable<E> {
private E[] elements;
private int size = 0;
@Override
public Iterator<E> iterator() {
return new CustomIterator();
}
private class CustomIterator implements Iterator<E> {
private int index = 0;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return elements[index++];
}
@Override
public void remove() {
// Логика удаления элемента
}
}
}
Ключевые различия: Iterator vs Stream
- Iterator: Императивный стиль, состояние хранит позицию
- Stream (Java 8+): Функциональный стиль, ленивые вычисления
// Iterator
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// Stream
list.stream()
.forEach(System.out::println);
Когда использовать
- Итератор: Когда нужно контролировать процесс итерации (удалять, двигаться туда-сюда)
- Enhanced for: Когда просто проходим по коллекции
- Stream: Для функциональной обработки данных (map, filter, reduce)