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 basicfor
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 basicfor
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 Iterable
s, 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
Calling Non-Static Method in Static Method in Java
Access Private Field of Another Object in Same Class
How to Return Datasnapshot Value as a Result of a Method
How to Use Java 8 For Android Development
Com.Android.Build.Transform.API.Transformexception
How to Parse Xml Using the Sax Parser
Difference Between Jsonobject and Jsonarray
How to Print My Java Object Without Getting "Sometype@2F92E0F4"
Why Does My Arraylist Contain N Copies of the Last Item Added to the List
How to Read/Convert an Inputstream into a String in Java
Including All the Jars in a Directory Within the Java Classpath
How to Download and Save a File from the Internet Using Java
Immutability of Strings in Java
Why Is January Month 0 in Java Calendar
How to Read the Value of a Private Field from a Different Class in Java