Home java How does a foreach loop in Java work?

How does a foreach loop in Java work?

Author

Date

Category

There is a collection and a loop foreach :

List & lt; String & gt; someList = new ArrayList & lt; String & gt; ();
// add "monkey", "donkey", "skeleton key" to someList
for (String item: someList)
 System.out.println (item);

What does the for loop look like, which is equivalent to the foreach loop above? How does the foreach loop work internally? What is the difference between for and foreach loops?


Answer 1, authority 100%

The

foreach loop is syntactic sugar. Outwardly, it primarily differs from for in the absence of an explicit counter. The only practical difference between the two is that in the case of indexed objects, you don’t have access to the index.

The foreach loop allows you to iterate over two types of objects:

  • T [] // arrays of any type
  • Objects that implement the Iterable .

for loop that works with Iterable

objects

Code from question

for (String item: someList)
   System.out.println (item);

is equal to the code below

for (Iterator & lt; E & gt; i = someIterable.iterator (); i.hasNext ();) {
  String item = i.next ();
  System.out.println (item);
}

This code works for any object that implements the interface Iterable .


In the foreach loop cannot be used method remove (index) . Use iterator.remove () instead. Example:

for (Iterator & lt; Integer & gt; iterator = list.iterator (); iterator.hasNext ();)
  if (iterator.next () & gt; 10)
    iterator.remove ();

If you write for without using an iterator, then here is an example implementation of foreach :

for (int i = 0; i & lt; list.size (); i ++)
 System.out.println (list.get (i));

foreach and for loops that work with arrays

String [] fruits = new String [] {"Orange", "Apple", "Pear", "Strawberry "};
for (String fruit: fruits) {
  // fruit is an element of the `fruits` array.
}

is essentially equivalent to

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

foreach vs. for – performance

When accessing a collection, foreach significantly faster than for . However, when accessing arrays – at least with arrays of primitives and wrappers – access via indices (i.e. using for ) is faster.

Also nested foreach performance problems occur from -for creating a large number of Iterator objects.


Java 8 introduced streams that perform better overall.
(although this information is not directly related to the question, but it can be useful)

To work with collections:

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

To work with an array:

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

Oracle Documentation for foreach .


UPD: Measuring Performance on JDK9

(do not seriously evaluate it, because it does not seem to me that I measured everything correctly)

To measure performance, I used code from this question:

public static void main (String [] args) {
  System.out.println (getTime ());
}
private static void testMethod () {
  // Code, the execution time of which you need to find out
}
/ **
 * Method for measuring the execution time of the testMethod method
 * https://stackoverflow.com/a/2404378/7150209
 * /
private static double getTime () {
for (int i = 0; i & lt; 20; i ++) {// warming up the JVM
    testMethod ();
  }
  int count = 1000; // initial number of times to retry testMethod
  while (true) {
    long begin = System.nanoTime ();
    for (int i = 0; i & lt; count; i ++)
      testMethod ();
    long end = System.nanoTime ();
    if ((end - begin) & lt; 1000000000) {// Run tests while total execution count times
      count * = 100000; // testMethod`a will not be equal for several seconds
      continue;
    }
    return (double) (end - begin) / count;
  }
}

How the getTime () method works – in the for loop, the method with the code under test is run count times. Before the start of the launches, the time is recorded, after all the launches, the initial time is subtracted from the end time – the time of launching count times of the test method is obtained. After that, the time is divided by count – the average time of one run of the test method is obtained. If the time to run count times the test method & lt; 10 seconds, then count is increased, and the measurement is repeated.

In the test method in the for and foreach loops, I used:
variable = list.get (i) / array [i] for for and variable = i; for foreach .

In the lambda, I used Arrays.stream (array) .map (l - & gt; l + 1) .collect (Collectors.toList ()); and list.stream () .map (l - & gt; l + 1) .collect (Collectors.toList ()) i.e. changing the elements of the collection and creating a new collection, so the lambdas took longer to execute.

The table shows that the execution in the lambda took about the same time for collections and arrays. The execution time of code with an array is about 1.5 times faster than with a collection. The execution time of the for and foreach loops is the same for all.

P.S. Example code for and foreach for a collection (n is just a variable):

for (int i = 0; i & lt; list.size (); i ++)
  n = list.get (i);

and

for (int i: list)
 n = i;

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions