Java: лучший способ перебора коллекции (здесь ArrayList) - PullRequest
91 голосов
/ 08 марта 2011

Сегодня я с радостью кодировал, когда попал к коду, который уже использовал сотни раз:

Итерация по коллекции (здесь ArrayList)

по какой-то причине, я на самом деле посмотрел опции автозаполнения Eclipse, и мне стало интересно:

В каких случаях следующие циклы лучше использовать, чем в других?

Классический цикл индекса массива:

for (int i = 0; i < collection.length; i++) {
  type array_element = collection.get(index);
}

Итератор hasNext () / next ():

for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
  type type = (type) iterator.next();   
}

И мой любимый, потому что его так просто написать:

for (iterable_type iterable_element : collection) {

}

Ответы [ 6 ]

98 голосов
/ 08 марта 2011

Первый полезен, когда вам нужен индекс элемента. Это в основном эквивалентно двум другим вариантам для ArrayList s, но будет очень медленным, если вы используете LinkedList.

Второй вариант полезен, когда вам не нужен индекс элемента, но может потребоваться удалить элементы во время итерации. Но у этого недостатка есть слишком многословный IMO.

Третья версия - мой предпочтительный выбор. Он короткий и работает для всех случаев, когда вам не нужны какие-либо индексы или лежащий в его основе итератор (т.е. вы только получаете доступ к элементам, не удаляя их или изменяя Collection любым способом - что является наиболее распространенным случаем).

35 голосов
/ 08 марта 2011

Все они имеют свое собственное использование:

  1. Если у вас есть итерация и вам необходимо безоговорочно перейти ко всем из них:

    для (iterable_typeiterable_element: collection)

  2. Если у вас есть итерация, но вам необходимо условно пройти:

    for (Iterator iterator = collection.iterator ();iterator.hasNext ();)

  3. Если структура данных не реализует итерируемый:

    для (int i = 0; i

11 голосов
/ 28 апреля 2016

Существует также функция stream () для коллекций с Java 8

collection.forEach((temp) -> {
            System.out.println(temp);
});

или

collection.forEach(System.out::println);

Дополнительная информация о потоке Java 8 и коллекциях для чудес ссылка

4 голосов
/ 08 марта 2011

Ни один из них не "лучше", чем другие. Третий для меня более читабелен, но для тех, кто не использует foreach, это может показаться странным (они могут предпочесть первое). Все 3 довольно понятны для любого, кто понимает Java, поэтому выбирайте то, что заставляет вас чувствовать себя лучше с кодом.

Первый - самый базовый, так что это самый универсальный шаблон (работает для массивов, всех итераций, которые я могу придумать). Это единственная разница, о которой я могу думать. В более сложных случаях (например, вам нужен доступ к текущему индексу или вам нужно отфильтровать список), первый и второй случаи могут иметь больше смысла соответственно. Для простого случая (повторяемый объект, без особых требований) третий кажется наиболее чистым.

2 голосов
/ 20 ноября 2015

Первый вариант лучше по производительности (как ArrayList реализует интерфейс RandomAccess).Согласно документу Java, реализация List должна реализовывать интерфейс RandomAccess, если для типичных экземпляров класса этот цикл:

 for (int i=0, n=list.size(); i < n; i++)
     list.get(i);

работает быстрее, чем этот цикл:

 for (Iterator i=list.iterator(); i.hasNext(); )
     i.next();

IНадеюсь, поможет.Первый вариант будет медленным для последовательных списков доступа.

1 голос
/ 23 марта 2016

Вот пример

Query query = em.createQuery("from Student");
             java.util.List list = query.getResultList();
             for (int i = 0; i < list.size(); i++) 
             {

                 student = (Student) list.get(i);
                 System.out.println(student.id  + "  " + student.age + " " + student.name + " " + student.prenom);

             }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...