For через итераторы java

Ways to iterate over a list in Java

Being somewhat new to the Java language I’m trying to familiarize myself with all the ways (or at least the non-pathological ones) that one might iterate through a list (or perhaps other collections) and the advantages or disadvantages of each. Given a List list object, I know of the following ways to loop through all elements:

Basic for loop (of course, there’re equivalent while / do while loops as well)

// Not recommended (see below)! for (int i = 0; i < list.size(); i++) < E element = list.get(i); // 1 - can call methods of element // 2 - can use 'i' to make index-based calls to methods of list // . >

Note: As @amarseillan pointed out, this form is a poor choice for iterating over List s, because the actual implementation of the get method may not be as efficient as when using an Iterator . For example, LinkedList implementations must traverse all of the elements preceding i to get the i-th element. In the above example there’s no way for the List implementation to «save its place» to make future iterations more efficient. For an ArrayList it doesn’t really matter, because the complexity/cost of get is constant time (O(1)) whereas for a LinkedList is it proportional to the size of the list (O(n)). For more information about the computational complexity of the built-in Collections implementations, check out this question.

Enhanced for loop (nicely explained in this question)

Iterator

for (Iterator iter = list.iterator(); iter.hasNext(); ) < E element = iter.next(); // 1 - can call methods of element // 2 - can use iter.remove() to remove the current element from the list // . >

ListIterator

for (ListIterator iter = list.listIterator(); iter.hasNext(); ) < E element = iter.next(); // 1 - can call methods of element // 2 - can use iter.remove() to remove the current element from the list // 3 - can use iter.add(. ) to insert a new element into the list // between element and iter->next() // 4 - can use iter.set(. ) to replace the current element // . > 

Functional Java

list.stream().map(e -> e + 1); // Can apply a transformation function for e 

Iterable.forEach, Stream.forEach, .

(A map method from Java 8’s Stream API (see @i_am_zero’s answer).) In Java 8 collection classes that implement Iterable (for example, all List s) now have a forEach method, which can be used instead of the for loop statement demonstrated above. (Here is another question that provides a good comparison.)

Arrays.asList(1,2,3,4).forEach(System.out::println); // 1 - can call methods of an element // 2 - would need reference to containing object to remove an item // (TODO: someone please confirm / deny this) // 3 - functionally separates iteration from the action // being performed with each item. Arrays.asList(1,2,3,4).stream().forEach(System.out::println); // Same capabilities as above plus potentially greater // utilization of parallelism // (caution: consequently, order of execution is not guaranteed, // see [Stream.forEachOrdered][stream-foreach-ordered] for more // information about this). 

What other ways are there, if any? (BTW, my interest does not stem at all from a desire to optimize performance; I just want to know what forms are available to me as a developer.)

Читайте также:  Ссылка на прокрутку html

Those are the non-pathological ones, although you might also use any of several functional-style libraries to process collections as well.

@SotiriosDelimanolis, for all intents and purposes, yes it is specific to List, but if there are other interesting ways to work with, say, a Collection, I’d be interested to know them.

@DaveNewton, thanks for the idea. I’ve never used anything like that. Please take a look at my edited question and let me know if I understood what you meant.

13 Answers 13

The three forms of looping are nearly identical. The enhanced for loop:

is, according to the Java Language Specification, identical in effect to the explicit use of an iterator with a traditional for loop. In the third case, you can only modify the list contents by removing the current element and, then, only if you do it through the remove method of the iterator itself. With index-based iteration, you are free to modify the list in any way. However, adding or removing elements that come before the current index risks having your loop skipping elements or processing the same element multiple times; you need to adjust the loop index properly when you make such changes.

In all cases, element is a reference to the actual list element. None of the iteration methods makes a copy of anything in the list. Changes to the internal state of element will always be seen in the internal state of the corresponding element on the list.

Essentially, there are only two ways to iterate over a list: by using an index or by using an iterator. The enhanced for loop is just a syntactic shortcut introduced in Java 5 to avoid the tedium of explicitly defining an iterator. For both styles, you can come up with essentially trivial variations using for , while or do while blocks, but they all boil down to the same thing (or, rather, two things).

EDIT: As @iX3 points out in a comment, you can use a ListIterator to set the current element of a list as you are iterating. You would need to use List#listIterator() instead of List#iterator() to initialize the loop variable (which, obviously, would have to be declared a ListIterator rather than an Iterator ).

Читайте также:  Что такое mixin php

Источник

Способы перебора списка в Java

Перебор элементов списка — одна из самых распространенных задач в программе.

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

2. для цикла​

Во-первых, давайте рассмотрим некоторые параметры цикла for .

Мы начнем с определения списка стран для наших примеров:

 ListString> countries = Arrays.asList("Germany", "Panama", "Australia"); 

2.1. Базовый цикл _ ​

Наиболее распространенным оператором управления потоком для итерации является базовый цикл for .

Цикл for определяет три типа операторов, разделенных точкой с запятой. Первый оператор является оператором инициализации. Второй определяет условие завершения. Последнее утверждение — это предложение обновления.

Здесь мы просто используем целочисленную переменную в качестве индекса:

 for (int i = 0; i  countries.size(); i++)    System.out.println(countries.get(i));   > 

При инициализации мы должны объявить целочисленную переменную, чтобы указать начальную точку. Эта переменная обычно действует как индекс списка.

Условие завершения — это выражение, которое возвращает логическое значение после оценки. Как только это выражение становится ложным, цикл завершается.

Предложение update используется для изменения текущего состояния индексной переменной, увеличения или уменьшения его до точки завершения.

2.2. Улучшено для цикла​

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

Обратите внимание, что расширенный цикл for проще, чем базовый цикл for :

 for (String country : countries)    System.out.println(country);   > 

3. Итераторы​

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

Этот способ обхода структур данных дает много преимуществ, среди которых мы можем подчеркнуть, что наш код не зависит от реализации.

Следовательно, структура может быть бинарным деревом или двусвязным списком, поскольку Итератор абстрагирует нас от способа выполнения обхода. Таким образом, мы можем легко заменить структуры данных в нашем коде без неприятных проблем.

3.1. Итератор ​

В Java шаблон Iterator отражен в классе java.util.Iterator . Он широко используется в коллекциях Java . В Iterator есть два ключевых метода: hasNext() и next() .

Здесь мы продемонстрируем использование обоих:

 IteratorString> countriesIterator = countries.iterator();    while(countriesIterator.hasNext())    System.out.println(countriesIterator.next());   > 

Метод hasNext() проверяет , остались ли какие-либо элементы в списке .

Метод next() возвращает следующий элемент итерации .

3.2. ListIterator ​

ListIterator позволяет нам перемещаться по списку элементов в прямом или обратном порядке.

Прокрутка списка с помощью ListIterator вперед следует механизму, аналогичному тому, который используется с помощью Iterator . Таким образом, мы можем переместить итератор вперед с помощью метода next() и найти конец списка с помощью метода hasNext() .

Как мы видим, ListIterator очень похож на итератор , который мы использовали ранее:

 ListIteratorString> listIterator = countries.listIterator();    while(listIterator.hasNext())    System.out.println(listIterator.next());   > 

4. для каждого() ​

4.1. Итерабельный.для каждого() ​

Начиная с Java 8, мы можем использовать метод forEach() для перебора элементов списка . Этот метод определен в интерфейсе Iterable и может принимать лямбда-выражения в качестве параметра.

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

До появления функции forEach все итераторы в Java были активны, то есть они включали цикл for или while, который обходил сбор данных до тех пор, пока не выполнялось определенное условие.

С введением forEach в качестве функции в интерфейсе Iterable все классы, реализующие Iterable , имеют добавленную функцию forEach .

4.2. Stream.forEach() ​

Мы также можем преобразовать набор значений в поток и получить доступ к таким операциям, как forEach() , map() и filter().

Здесь мы продемонстрируем типичное использование потоков:

 countries.stream().forEach((c) -> System.out.println(c)); 

5. Вывод​

В этой статье мы продемонстрировали различные способы перебора элементов списка с помощью Java API. Эти параметры включали цикл for , расширенный цикл for , Iterator , ListIterator и метод forEach() (включенный в Java 8).

Затем мы узнали, как использовать метод forEach() с потоками .

Наконец, весь код, используемый в этой статье, доступен в нашем репозитории Github .

Источник

Расширенный цикл For (цикл For-Each) в Java

В Java есть четыре типа циклов: for-loop, для каждого цикла, цикл while и цикл do-while. В этом посте представлен обзор конструкции for-each в Java.

The foreach-конструкция — это оператор потока управления, представленный в Java 1.5, упрощающий перебор элементов в массиве или коллекции. Цикл For-Each обычно используется вместо стандартного оператора for, когда счетчик циклов на самом деле не нужен и необходимо обработать каждый элемент в коллекции. Его также называют расширенным циклом for, циклом For-Each и циклом For-Each. ForEach утверждение.

Синтаксис расширенного цикла for:

Приведенный выше цикл читается как “для каждого элемента Type в iterableCollection”, где двоеточие (:) означает в.

Обратите внимание на разницу между стандартный цикл for и для каждого цикла. Синтаксис значительно упрощен, и в цикле нет явного счетчика: по сути, они говорят “сделай это со всем в этой коллекции”, а не “сделай это”. x раз».

Нужен расширенный цикл for?

Рассмотрим следующий код, который использует итератор для обхода коллекции.

результат:

Blue
Red
Green

В приведенном выше коде для обхода списка используется итератор, что просто уродливо и трудно читаемо. Кроме того, он имеет большой потенциал для ошибок, поскольку он использует дженерики, а переменная итератора используется в коде несколько раз. Конструкция for-each упрощает код, скрывая сложность за кулисами. (ForEach внутренне вызывает iterator() метод). Кроме того, об дженериках заботится сам компилятор, и безопасность типов кода сохраняется.

Теперь давайте посмотрим, как приведенный выше код преобразуется с помощью конструкции for-each:

Источник

Оцените статью