How Does the Java 'For Each' Loop Work

How does the Java 'for each' loop work?

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.

How does for-each loop works internally in JAVA?

I'm not going to copy paste from the Java Language Specification, like one of the previous answers did, but instead interpret the specification in a readable format.

Consider the following code:

for (T x : expr) {
// do something with x
}

If expr evaluates to an array type like in your case, the language specification states that the resulting bytecode will be the same as:

T[] arr = expr;
for (int i = 0; i < arr.length; i++) {
T x = arr[i];
// do something with x
}

The difference only is that the variables arr and i will not be visible to your code - or the debugger, unfortunately. That's why for development, the second version might be more useful: You have the return value stored in a variable accessible by the debugger.

In your first version expr is simply the function call, while in the second version you declare another variable and assign the result of the function call to that, then use that variable as expr. I'd expect them to exhibit no measurable difference in performance, as that additional variable assignment in the second version should be optimized away by the JIT compiler, unless you also use it elsewhere.

How does a for-each loop work?

According to the Java Language Specification for the enhanced for statement, the expression:

for ( FormalParameter : Expression ) Statement

Is executed as follows:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
VariableModifiersopt TargetType Identifier =
(TargetType) #i.next();
Statement
}

Thus, the Expression (which must be of type Iterable) only has its iterator() method called once.

What's happening under the hood of an enhanced for loop?

The enhanced for loop is covered by the JLS, Section 14.14.2:

  • For Iterable objects:

The enhanced for statement is equivalent to a basic for statement of the form:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
{VariableModifier} TargetType Identifier =
(TargetType) #i.next();
Statement
}
  • For arrays:

The enhanced for statement is equivalent to a basic for statement of the form:

T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
{VariableModifier} TargetType Identifier = #a[#i];
Statement
}

It creates a new reference to the array, separate from your original reference. You can modify the reference to the array all you want, but it will still keep iterating over this implicit reference to the original array.

Over Iterables, only the reference to the Iterator is kept, which still refers back to the original Iterable object, even if you reassign the original variable during the loop.

Whether you use an enhanced for loop over an array or an Iterable, you can reassign the reference used as the target without affecting the result of the iteration -- you will still iterate over the original object referred by the target reference.

does index start at 1 for enhanced for loop

For loops are appropriate loops when you know exactly how many times iteration you want in statements within the loop.
For loop iterates a statement or a block of statements repeatedly until a specified expression evaluates to false.
In the case of for the variable of the loop is always be int only.

For-each loop is used to iterate through the items in object collections, List generic collections, or array list collections.
In the case of Foreach the variable of the loop while being the same as the type of values under the array.

For each loop do not keep track of the index. So we can not obtain array index using For-Each loop

In your code in for each loop, you get object by index like l.get(i);

l is the Arraylist type and it stores the value from 0 index. Also, your ArrayList contains an integer value. When you reach at 6th object at that time you are accessing l.get(6) at that time IndexOutOfBoundsException throws.

So, remove l.get(i); from your program.

Java for each loop working

Now I just want to know what is happening behind the every for each
loop quoted above

 1. for (String output : splitted) 
{
mylist.add(output);
}

This adds each output String from splitted array to the mylist list.

2. for (String output : mylist) 
{
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}

The for statement is governed by the following production:

for ( FormalParameter : Expression )
Statement

where Expression must be an instance of java.lang.Iterable, or an array. So this for:each loop is equivalent to this:

Iterator<String> iterator = mylist.iterator();
while (iterator.hasNext()) {
System.out.println(output);
mylist = new ArrayList<String>(); //It worked
mylist.add(output);
}

Here mylist.iterator() will return a new instance of Iterator type:

public Iterator<E> iterator() {
return new Itr();
}

So even if you are creating new ArrayList instances and assigning them to mylist on each iteration, the iterator obtained from the original mylist will still have a reference to the original mylist and will keep iterating through the elements of original mylist. The iterator keeps a reference to the list it was created on. The assignment mylist = new ArrayList<String>() has no effect on the data that the iterator works on because it changes the variable mylist and not the list itself.

3. for (String output : mylist) 
{
System.out.println(output);
mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException
}

Below statement explains this behavior. It is copied from Arraylist doc:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

4. for (Iterator iterator2 = mylist.iterator(); iterator2.hasNext();)
{
String string = (String) iterator2.next();
System.out.println(string);
iterator2.remove(); //It worked but if I used the same thing to remove element from original list it threw exception.
}

The above statement also explains the behavior of this for loop: the list can be structurally modified by the iterator's own remove or add methods while iterating through the list.

How for each loop is working in this rectangular array?

2D-arrays in java are actually not 2D arrays, but an array of arrays, so what happens is the 1D array would contain references to other arrays(rows). When the loop is entered and an array is set for each iteration, it's just following a reference to get that array and then get its size using arr1.length(which is the size of that array which would be the column number of the base array)

How does a for each loop guard against an empty list?

My question is how does a for each loop work for an empty list

ForEach also works in the same way. If the length is zero then loop is never executed.

The only difference between them is use ForEach loop when you want to iterate all the items of the list or array whereas in case of normal for loop you can control start and end index.



Related Topics



Leave a reply



Submit