Как работает Java для каждого цикла? - PullRequest
1384 голосов
/ 17 сентября 2008

Рассмотрим:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

Как будет выглядеть эквивалентный цикл for без использования для каждого синтаксиса ?

Ответы [ 26 ]

15 голосов
/ 04 октября 2012

Концепция цикла foreach, упомянутая в Википедии, выделена ниже:

В отличие от других для циклических конструкций, циклы foreach обычно поддерживать без явного счетчика : они, по сути, говорят "сделать это все в этом наборе ", а не" сделать это х раз ". Это позволяет избежать потенциальные ошибочные ошибки и упрощают чтение кода.

Таким образом, концепция цикла foreach описывает, что цикл не использует какой-либо явный счетчик, что означает, что нет необходимости использовать индексы для перемещения по списку, таким образом, он спасает пользователя от ошибки «один на один». Чтобы описать общую концепцию этой ошибки, давайте возьмем пример цикла для перемещения по списку с использованием индексов.

// In this loop it is assumed that the list starts with index 0
for(int i=0; i<list.length; i++){

}

Но предположим, что если список начинается с индекса 1, то этот цикл будет выдавать исключение, так как он не найдет элемент с индексом 0, и эта ошибка называется ошибкой «один за другим». Поэтому, чтобы избежать этой ошибки, используется концепция цикла foreach. Могут быть и другие преимущества, но это то, что я считаю основной концепцией и преимуществом использования цикла foreach.

11 голосов
/ 17 сентября 2008
for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}
9 голосов
/ 17 сентября 2008

Вот эквивалентное выражение.

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}
9 голосов
/ 17 сентября 2008

Также обратите внимание, что использование метода "foreach" в исходном вопросе имеет некоторые ограничения, такие как невозможность удаления элементов из списка во время итерации.

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

9 голосов
/ 21 июня 2018

Используя более старые версии Java, включая Java 7, вы можете использовать цикл foreach следующим образом.

List<String> items = new ArrayList<>();
        items.add("A");
        items.add("B");
        items.add("C");
        items.add("D");
        items.add("E");

        for(String item : items){
            System.out.println(item);
        }

Ниже приведен самый последний способ использования петли foreach в Java 8

.

(цикл списка с forEach + лямбда-выражением или ссылкой на метод)

//lambda
    //Output : A,B,C,D,E
    items.forEach(item->System.out.println(item));


//method reference
    //Output : A,B,C,D,E
    items.forEach(System.out::println);

Для получения дополнительной информации перейдите по этой ссылке.

https://www.mkyong.com/java8/java-8-foreach-examples/

8 голосов
/ 17 мая 2017

Альтернатива forEach, чтобы избежать вашего «для каждого»:

List<String> someList = new ArrayList<String>();

Вариант 1 (простой):

someList.stream().forEach(listItem -> {
    System.out.println(listItem);
});

Вариант 2 (параллельное выполнение (быстрее)):

someList.parallelStream().forEach(listItem -> {
    System.out.println(listItem);
});
7 голосов
/ 30 сентября 2015

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

Обычный for цикл:

void cancelAll(Collection<TimerTask> list) {
    for (Iterator<TimerTask> i = list.iterator(); i.hasNext();)
         i.next().cancel();
}

Использование for-each:

void cancelAll(Collection<TimerTask> list) {
    for (TimerTask t : list)
        t.cancel();
}

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

Следующая строка читается как " для каждого TimerTask t в списке. "

for (TimerTask t : list)

Существует меньше шансов на ошибки в случае для каждого. Вам не нужно беспокоиться об инициализации итератора или об инициализации счетчика цикла и его завершении (там, где есть место для ошибок).

6 голосов
/ 30 августа 2018

В Java 8 они представлены для forEach. Используя этот список, можно зацикливать карты.

Цикл использования списка для каждого

List<String> someList = new ArrayList<String>();
someList.add("A");
someList.add("B");
someList.add("C");

someList.forEach(listItem -> System.out.println(listItem))

или

someList.forEach(listItem-> {
     System.out.println(listItem); 
});

Цикл карты, используя для каждого

Map<String, String> mapList = new HashMap<>();
    mapList.put("Key1", "Value1");
    mapList.put("Key2", "Value2");
    mapList.put("Key3", "Value3");

mapList.forEach((key,value)->System.out.println("Key: " + key + " Value : " + value));

или

mapList.forEach((key,value)->{
    System.out.println("Key : " + key + " Value : " + value);
});
6 голосов
/ 27 февраля 2018

До Java 8 вам необходимо использовать следующее:

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
}

Однако с появлением Streams в Java 8 вы можете делать то же самое с гораздо меньшим синтаксисом. Например, для вашего someList вы можете сделать:

someList.stream().forEach(System.out::println);

Подробнее о потоках можно узнать здесь .

6 голосов
/ 17 сентября 2008

Это будет выглядеть примерно так. Очень грубый

for (Iterator<String> i = someList.iterator(); i.hasNext(); )
        System.out.println(i.next());

Существует хорошая запись на для каждого в документации Sun .

...