Java for each loop
I'm working on a task when I accidentally make a mistake, but the code executes and provides the correct result I was a little surprised and remembered how all this worked for each loop
public static void main( String[] args ) { String myInput = "hello,hi,how are you "; String[] splitted = myInput.split(","); List<String> mylist = new ArrayList<String>(); for (String output : splitted) { mylist.add(output); } for (String output : mylist) { System.out.println(output); mylist = new ArrayList<String>(); //It worked mylist.add(output); } for (String output : splitted) { mylist.add(output); } for (String output : mylist) { System.out.println(output); mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException } }
I'd like to know that during the search, I found another article saying that if we use the iterator method, we can delete elements from the list, so I tried,
for (String output : splitted) { mylist.add(output); } 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. }
Now I just want to know what happens behind each loop referenced above I want to know the technical aspect. I know I can't modify the set of each loop, but in some cases, how does it work?
Solution
1. for (String output : splitted) { mylist.add(output); }
This adds each output string in the split 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 managed by the following products:
for ( FormalParameter : Expression ) Statement
Where expression must be Java Lang. Iterable or an instance of an array So each cycle is equivalent to:
Iterator<String> iterator = mylist.iterator(); while (iterator.hasNext()) { System.out.println(output); mylist = new ArrayList<String>(); //It worked mylist.add(output); }
Here is mylist Iterator () will return a new instance of iterator type:
public Iterator<E> iterator() { return new Itr(); }
Therefore, even if you are creating new ArrayList instances and assigning them to mylist at each iteration, the iterator obtained from the original mylist will still have a reference to the original mylist and will continue to iterate over the elements of the original mylist An iterator maintains a reference to the list it creates The assignment mylist = new ArrayList < string > () has no effect on the data processed by the iterator because it changes the variable mylist rather than the list itself
3. for (String output : mylist) { System.out.println(output); mylist.add(output); // After this line it threw exception java.util.ConcurrentModificationException }
The following statement explains this behavior It is copied from ArrayList doc:
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 the for loop: when iterating through the list, the iterator's own remove or add methods can modify the list structurally