Класс Iterator

В java.util есть класс Iterator, который может использоваться, когда итерация по списку или другой коллекции предполагает удаление элементов. Удалять элементы в цикле обхода последовательности for each нельзя.

Из списка с помощью метода iterator() создается объект-итератор, который присваивается переменной типа Iterator.

Далее из объекта-итератора в цикле извлекаются элементы с помощью метода next(). Проверка, есть ли следующий элемент, выполняется методом hasNext(). Удаляют элементы методом remove().

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
 
public class IteratorTest {
    public static void main(String[] args) {
        Integer[] nums = {10, -5, 4, 8, -2, -10, 1, 4, 2};
        ArrayList<Integer> numList = new ArrayList<>(Arrays.asList(nums));
 
        Iterator<Integer> numListIter = numList.iterator();
        while (numListIter.hasNext()) {
            int n = numListIter.next();
            if (n < 0) {
                numListIter.remove();
            }
        }
 
        System.out.println(numList);
 }
}

Примечание. В примере обычный массив преобразуется в список с помощью метода asList().

Отдельное создание итератора и передачу его в цикл while можно заменить циклом for:

for (Iterator<Integer> it = numList.iterator(); it.hasNext();) {
    int n = it.next();
    if (n < 0)
        it.remove();
}

Однако, несмотря на наличие в Java класса Iterator, не рекомендуется его использовать в подобных целях. У коллекций есть метод removeIf(), которому передается фильтр. Если элемент подходит под него, то он также как в случае итератора безопасно удаляется. Например, команда

numList.removeIf(n -> (n < 0));

удалит из списка все числа меньше нуля.

Основным назначением итераторов был обход элементов множеств и словарей, поскольку в данных коллекциях отсутствует упорядоченная индексация элементов.

import java.util.HashSet;
import java.util.Iterator;
 
public class Iter {
    public static void main(String[] args) {
        HashSet<String> s = new HashSet<>();
        s.add("hello");
        s.add("hi");
        s.add("hey");
 
        Iterator<String> i = s.iterator();
        while (i.hasNext()) {
            System.out.println(i.next());
        }
    }
}

Однако вместо явного создания итераторов в таких случаях рекомендуется использовать цикл for each, в котором итератор создается неявно:

HashSet<String> s = new HashSet<>();
s.add("hello");
s.add("hi");
s.add("hey");
 
for (String s1 : s) {
    System.out.println(s1);
}

Создано