Интерфейс Java Iterator используется для итерации по элементам Collection( List, Set или Map ). Iterator помогает извлекать элементы из указанной коллекции один за другим и опционально выполняет операции над каждым элементом.
Java Iterator был впервые представлен в Java 1.2 как замена Enumerations. Обратите внимание, что, за исключением ListIterator, он не гарантирует порядок итерации других типов коллекций.
1. Введение в итератор
Все классы коллекций Java предоставляют метод iterator(), который возвращает экземпляр Iterator для обхода элементов в этой коллекции. Например, метод ArrayList.iterator() возвращает итератор по элементам в этом ArrayList в правильной последовательности.
ArrayList<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");list.add("D");Iterator<String> iterator = list.iterator();while(iterator.hasNext()) {System.out.println( iterator.next() );}
2. Методы итератора
Интерфейс Iterator имеет 4 метода, используемых для выполнения различных операций:
- hasNext()
- следующий()
- удалять()
- forEachRemaining()
2.1.Итератор.hasNext()
- Этот метод возвращает значение true, если в итерации осталось еще несколько элементов в коллекции.
- Если итератор прошел по всем элементам, то этот метод вернет false.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);Iterator<Integer> iterator = numbers.iterator();boolean result = iterator.hasNext(); //true
2.2.Итератор.next()
- Этот метод возвращает следующий элемент в итерации.
- Он выдает исключение NoSuchElementException, если в итерации больше нет элементов.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);Iterator<Integer> iterator = numbers.iterator();int number = iterator.next(); //1int number = iterator.next(); //2
2.3.Итератор.remove()
- Он удаляет из базовой коллекции последний элемент, возвращенный итератором(необязательная операция).
- Этот метод можно вызвать только один раз за один вызов next().
- Если базовая коллекция изменяется во время выполнения итерации каким-либо образом, кроме вызова метода remove(), итератор выдаст исключение ConcurrentModificationException.
- Итераторы, которые делают это, называются итераторами с быстрым отказом, поскольку они быстро и аккуратно выходят из строя, не рискуя при этом проявить произвольное, недетерминированное поведение в неопределенное время в будущем.
List<Integer> numbers = List.of(1, 2, 3, 4, 5);Iterator<Integer> iterator = numbers.iterator();int number = iterator.next(); //1iterator.remove();System.out.println(numbers); [2, 3, 4, 5]
2.4.Итератор.forEachRemaining()
- Этот метод выполняет заданное действие для каждого оставшегося элемента до тех пор, пока все элементы не будут обработаны или пока действие не выдаст исключение.
- Действия выполняются в порядке итерации, если такой порядок указан.
- Он выдает исключение NullPointerException, если указанное действие равно null.
В следующем примере мы передали лямбда-выражение в качестве аргумента метода forEachRemaining().
List<Integer> numbers = List.of(1, 2, 3, 4, 5);Iterator<Integer> iterator = numbers.iterator();while(iterator.hasNext()) {iterator.forEachRemaining(System.out::println); //1 2 3 4 5}
3. Примеры итераторов
3.1. Итерация по ArrayList
Пример Java для перебора элементов ArrayList.
ArrayList<String> list = new ArrayList<>();Iterator<String> iterator = list.iterator();while(iterator.hasNext()){String value = iterator.next();//perform other operation on the element}
3.2 Итерация по HashSet
Итерация по HashSet очень похожа на итерацию по List. Видимых различий нет.
HashSet<String> set = new HashSet<>();Iterator<String> iterator = set.iterator();while(iterator.hasNext()){String value = iterator.next();//perform other operation on the element}
3.2 Итерация по ключам и значениям карты
Пример Java для перебора ключей и значений HashMap.
HashMap<Integer, String> map = new HashMap<>();//Iterating over map keysIterator<String> iterator = map.keys().iterator();while(iterator.hasNext()){String key = iterator.next();System.out.println( "Key : " + key + ", Value : " + map.get(key) );}//Iterating over map valuesIterator<String> iterator = map.values().iterator();while(iterator.hasNext()){System.out.println( "Value : " + iterator.next() );}
4. Преобразовать итератор в поток
мы можем преобразовать итератор в поток, сначала преобразовав итератор в Spliterator, а затем используя StreamSupport для получения потока из Spliterator.
// IteratorIterator<String> iterator = Arrays.asList("a", "b", "c").listIterator();//Extra step to get SpliteratorSpliterator<String> splitItr = Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED);// Iterator -> StreamStream<String> stream = StreamSupport.stream(splitItr, false);// Apply stream operationsstream.forEach(System.out::println);
5. Заключение
В этом уроке мы изучили интерфейс Java Iterator. Мы изучили методы итератора и простые примеры для итерации по различным коллекциям, таким как List, Set и Map.
Пишите мне свои вопросы в комментариях.