I was working on certain task, when incidentally did something wrong according to me but the code executed and provided correct result. I was little surpris
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(); //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 iterator = mylist.iterator();
while (iterator.hasNext()) {
System.out.println(output);
mylist = new ArrayList(); //It worked
mylist.add(output);
}
Here mylist.iterator()
will return a new instance of Iterator
type:
public Iterator 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
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.