Рубрики

Итератор против Foreach в Java

Фон :

Iterator — это интерфейс, предоставляемый платформой коллекции для обхода коллекции и для последовательного доступа к элементам в коллекции.

   
   // Iterating over collection 'c' using terator
   for (Iterator i = c.iterator(); i.hasNext(); ) 
       System.out.println(i.next());

Для каждого цикла предназначен для прохождения предметов в коллекции.

   // Iterating over collection 'c' using for-each 
   for (Element e: c)
       System.out.println(e);

Мы читаем «:», используемый в цикле for-each, как «in». Таким образом, цикл читается как «для каждого элемента e в элементах», здесь elements — это коллекция, в которой хранятся элементы типа Element.

Примечание. В Java 8 с использованием лямбда-выражений мы можем просто заменить цикл for-each на

 elements.forEach (e -> System.out.println (e)); 

Разница между двумя обходами

В цикле for-each мы не можем модифицировать коллекцию, с другой стороны, она создает исключение ConcurrentModificationException с итератором, который мы можем модифицировать коллекцией.

Модификация коллекции просто означает удаление элемента или изменение содержимого элемента, хранящегося в коллекции. Это происходит потому, что цикл for-each неявно создает итератор, но он не предоставляется пользователю, поэтому мы не можем изменять элементы в коллекциях.

Когда использовать какой обход?

  • Если нам нужно изменить коллекцию, мы можем использовать Iterator.
  • При использовании вложенных циклов for лучше использовать цикл for-each, для лучшего понимания рассмотрим приведенный ниже код.

// Java-программа для демонстрации работы вложенных итераторов
// может работать не так, как ожидается, и генерировать исключение.

import java.util.*;

  

public class Main

{

    public static void main(String args[])

    {

        // Создаем список ссылок, в котором хранятся целочисленные элементы

        List<Integer> l = new LinkedList<Integer>();

  

        // Теперь добавляем элементы в список ссылок

        l.add(2);

        l.add(3);

        l.add(4);

  

        // Создание другого списка ссылок, в котором хранятся целочисленные элементы

        List<Integer> s=new LinkedList<Integer>();

        s.add(7);

        s.add(8);

        s.add(9);

  

        // Итератор для перебора списка ссылок

        for (Iterator<Integer> itr1=l.iterator(); itr1.hasNext(); )

        {

            for (Iterator<Integer> itr2=s.iterator(); itr2.hasNext(); )

            {

                if (itr1.next() < itr2.next())

                {

                    System.out.println(itr1.next());

                }

            }

        }

    }

}

Выход:

 Исключение в потоке main java.util.NoSuchElementException
    at java.util.LinkedList $ ListItr.next (LinkedList.java:888)
    в Main.main (Main.java:29) 

Приведенный выше код вызывает исключение java.util.NoSuchElementException.

В приведенном выше коде мы снова и снова вызываем метод next () для itr1 (т. Е. Для List l). Теперь мы продвигаем итератор, даже не проверяя, осталось ли у него больше элементов в коллекции (во внутреннем цикле), таким образом, мы продвигаем итератор больше, чем количество элементов в коллекции, что приводит к NoSuchElementException.

циклы for-each сделаны специально для вложенных циклов. Замените код итератора приведенным ниже кодом.

// Java-программа для демонстрации работы вложенных для каждого

import java.util.*;

public class Main

{

    public static void main(String args[])

    {

        // Создаем список ссылок, в котором хранятся целочисленные элементы

        List<Integer> l=new LinkedList<Integer>();

  

        // Теперь добавляем элементы в список ссылок

        l.add(2);

        l.add(3);

        l.add(4);

  

        // Создание другого списка ссылок, в котором хранятся целочисленные элементы

        List<Integer> s=new LinkedList<Integer>();

        s.add(2);

        s.add(4);

        s.add(5);

        s.add(6);

  

        // Итератор для перебора списка ссылок

        for (int a:l)

        {

            for (int b:s)

            {

                if (a<b)

                    System.out.print(a + " ");

            }

        }

    }

}

Выход:

2 2 2 3 3 3 4 4 

Анализ производительности

Обход коллекции с использованием циклов for-each или итераторов дает одинаковую производительность. Здесь под производительностью мы понимаем временную сложность обоих этих обходов.

Если вы выполняете итерацию с использованием старого стилизованного цикла C for, то мы можем значительно увеличить временную сложность.

// Здесь l — список, это может быть ArrayList / LinkedList, а n — размер списка

for (i=0;i<n;i++)
   System.out.println(l.get(i));

Здесь, если список l является ArrayList, то мы можем получить к нему доступ за O (1) раз, так как он выделен смежными блоками памяти (как массив), то есть возможен произвольный доступ. Но если коллекция представляет собой LinkedList, то произвольный доступ невозможен, поскольку для него не выделены смежные блоки памяти, поэтому, чтобы получить доступ к элементу, нам придется просматривать список ссылок, пока вы не доберетесь до требуемого индекса, таким образом, время, затрачиваемое на в худшем случае для доступа к элементу будет O (n).

Итератор и цикл for-each быстрее, чем простой цикл for для коллекций без произвольного доступа, в то время как в коллекциях, которые допускают произвольный доступ, нет изменений производительности для цикла for-each / for loop / iterator.

Статьи по Теме:
Итераторы в Java
Извлечение элементов из коллекции в Java (For-each, Iterator, ListIterator & EnumerationIterator)

Ссылки:
https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html
https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
https://stackoverflow.com/questions/2113216/which-is-more-efficient-a-for-each-loop-or-an-iterator

Эта статья предоставлена Чирагом Агарвалом . Если вам нравится GeeksforGeeks и вы хотите внести свой вклад, вы также можете написать статью и отправить ее по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Итератор против Foreach в Java

0.00 (0%) 0 votes