Класс 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); }