How does the Java 'for each' loop work?

Viewed 2843794

Consider:

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

What would the equivalent for loop look like without using the for each syntax?

29 Answers
for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
    String item = i.next();
    System.out.println(item);
}

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for ( : ) idiom, since the actual iterator is merely inferred.

As was noted by Denis Bueno, this code works for any object that implements the Iterable interface.

Also, if the right-hand side of the for (:) idiom is an array rather than an Iterable object, the internal code uses an int index counter and checks against array.length instead. See the Java Language Specification.

The construct for each is also valid for arrays. e.g.

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

which is essentially equivalent of

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

So, overall summary:
[nsayer] The following is the longer form of what is happening:

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

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

[Denis Bueno]

It's implied by nsayer's answer, but it's worth noting that the OP's for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

The for-each loop in Java uses the underlying iterator mechanism. So it's identical to the following:

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

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

It's implied by nsayer's answer, but it's worth noting that the OP's for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

A foreach loop syntax is:

for (type obj:array) {...}

Example:

String[] s = {"Java", "Coffe", "Is", "Cool"};
for (String str:s /*s is the array*/) {
    System.out.println(str);
}

Output:

Java
Coffe
Is
Cool

WARNING: You can access array elements with the foreach loop, but you can NOT initialize them. Use the original for loop for that.

WARNING: You must match the type of the array with the other object.

for (double b:s) // Invalid-double is not String

If you want to edit elements, use the original for loop like this:

for (int i = 0; i < s.length-1 /*-1 because of the 0 index */; i++) {
    if (i==1) //1 because once again I say the 0 index
        s[i]="2 is cool";
    else
        s[i] = "hello";
}

Now if we dump s to the console, we get:

hello
2 is cool
hello
hello

The Java "for-each" loop construct will allow iteration over two types of objects:

  • T[] (arrays of any type)
  • java.lang.Iterable<T>

The Iterable<T> interface has only one method: Iterator<T> iterator(). This works on objects of type Collection<T> because the Collection<T> interface extends Iterable<T>.

In Java 8, they introduced forEach. Using it List, Maps can be looped.

Loop a List using for each

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

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

or

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

Loop a Map using for each

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));

or

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

Here's an equivalent expression.

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

Using older Java versions, including Java 7, you can use a foreach loop as follows.

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);
}

The following is the very latest way of using a for each loop in Java 8 (loop a List with forEach + lambda expression or method reference).

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);

For more information, refer to "Java 8 forEach examples".

for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}

Also note that using the "foreach" method in the original question does have some limitations, such as not being able to remove items from the list during the iteration.

The new for-loop is easier to read and removes the need for a separate iterator, but is only really usable in read-only iteration passes.

It would look something like this. Very crufty.

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

There is a good writeup on for each in the Sun documentation.

The Java for each loop (aka enhanced for loop) is a simplified version of a for loop. The advantage is that there is less code to write and less variables to manage. The downside is that you have no control over the step value and no access to the loop index inside the loop body.

They are best used when the step value is a simple increment of 1 and when you only need access to the current loop element. For example, if you need to loop over every element in an array or Collection without peeking ahead or behind the current element.

There is no loop initialization, no boolean condition and the step value is implicit and is a simple increment. This is why they are considered so much simpler than regular for loops.

Enhanced for loops follow this order of execution:

1) loop body

2) repeat from step 1 until entire array or collection has been traversed

Example – Integer Array

int [] intArray = {1, 3, 5, 7, 9};
for(int currentValue : intArray) {
  System.out.println(currentValue);
}

The currentValue variable holds the current value being looped over in the intArray array. Notice there’s no explicit step value – it’s always an increment by 1.

The colon can be thought of to mean “in”. So the enhanced for loop declaration states: loop over intArray and store the current array int value in the currentValue variable.

Output:

1
3
5
7
9

Example – String Array

We can use the for-each loop to iterate over an array of strings. The loop declaration states: loop over myStrings String array and store the current String value in the currentString variable.

String [] myStrings  = {
  "alpha",
  "beta",
  "gamma",
  "delta"
};

for(String currentString : myStrings) {
  System.out.println(currentString);
}

Output:

alpha
beta
gamma
delta

Example – List

The enhanced for loop can also be used to iterate over a java.util.List as follows:

List<String> myList = new ArrayList<String>();
myList.add("alpha");
myList.add("beta");
myList.add("gamma");
myList.add("delta");

for(String currentItem : myList) {
  System.out.println(currentItem);
}

The loop declaration states: loop over myList List of Strings and store the current List value in the currentItem variable.

Output:

alpha
beta
gamma
delta

Example – Set

The enhanced for loop can also be used to iterate over a java.util.Set as follows:

Set<String> mySet = new HashSet<String>();
mySet.add("alpha");
mySet.add("alpha");
mySet.add("beta");
mySet.add("gamma");
mySet.add("gamma");
mySet.add("delta");

for(String currentItem : mySet) {
  System.out.println(currentItem);
}

The loop declaration states: loop over mySet Set of Strings and store the current Set value in the currentItem variable. Notice that since this is a Set, duplicate String values are not stored.

Output:

alpha
delta
beta
gamma

Source: Loops in Java – Ultimate Guide

As many of other answers correctly state, the for each loop is just syntactic sugar over the same old for loop and the compiler translates it to the same old for loop.

javac (OpenJDK) has a switch, -XD-printflat, which generates a Java file with all the syntactic sugar removed. The complete command looks like this:

javac -XD-printflat -d src/ MyFile.java

//-d is used to specify the directory for output java file

So let’s remove the syntactical sugar

To answer this question, I created a file and wrote two versions of for each, one with array and another with a list. My Java file looked like this:

import java.util.*;

public class Temp{

    private static void forEachArray(){
        int[] arr = new int[]{1,2,3,4,5};
        for(int i: arr){
            System.out.print(i);
        }
    }

    private static void forEachList(){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        for(Integer i: list){
            System.out.print(i);
        }
    }
}

When I compiled this file with above switch, I got the following output.

import java.util.*;

public class Temp {

    public Temp() {
        super();
    }

    private static void forEachArray() {
        int[] arr = new int[]{1, 2, 3, 4, 5};
        for (/*synthetic*/ int[] arr$ = arr, len$ = arr$.length, i$ = 0; i$ < len$; ++i$) {
            int i = arr$[i$];
            {
                System.out.print(i);
            }
        }
    }

    private static void forEachList() {
        List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3), Integer.valueOf(4), Integer.valueOf(5)});
        for (/*synthetic*/ Iterator i$ = list.iterator(); i$.hasNext(); ) {
            Integer i = (Integer)i$.next();
            {
                System.out.print(i);
            }
        }
    }
}

You can see that along with the other syntactic sugar (Autoboxing), for each loops got changed to simple loops.

public static Boolean Add_Tag(int totalsize)
{
    List<String> fullst = new ArrayList<String>();
    for(int k=0; k<totalsize; k++)
    {
        fullst.addAll();
    }
}

This looks crazy but hey it works

List<String> someList = new ArrayList<>(); //has content
someList.forEach(System.out::println);

This works. Magic

I think this will work:

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

The code would be:

import java.util.ArrayList;
import java.util.List;

public class ForLoopDemo {

  public static void main(String[] args) {

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

    someList.add("monkey");
    someList.add("donkey");
    someList.add("skeleton key");

    // Iteration using For Each loop
    System.out.println("Iteration using a For Each loop:");
    for (String item : someList) {
      System.out.println(item);
    }

    // Iteration using a normal For loop
    System.out.println("\nIteration using normal For loop: ");
    for (int index = 0; index < someList.size(); index++) {
      System.out.println(someList.get(index));
    }
  }
}

Using forEach:

int[] numbers = {1,2,3,4,5};

Arrays.stream(numbers).forEach(System.out::println);

Response:

1
2
3
4
5

The process finished with exit code 0

PS: You need a Array (int[] numbers), and import java.util.Arrays;

Related