-1

I'm studying for java 8 certification, and I discovered an incredible thing!

I'm attending a course, during explanation about List in Java he talk about ConcurrentModificationException.

Look at this fragment:

List<String> lista = new LinkedList<>();

lista.add("d");
lista.add("d");
lista.add("d");
lista.add("d");

for(int i = 0; i<lista.size(); i++){
    System.out.println(lista.get(i));

}

for(String s : lista){
    lista.add(s);
}}

Why java without ITERATOR throw ConcurrentModificationException?

Should not the list be read from the first cycle, and only once it has finished with the first one start with the second?

How can the second loop be executed while the first is still iterating?

resla95
  • 1,017
  • 2
  • 11
  • 18
  • 6
    It's not the two loops that's the problem - it's the fact that the second loop is **modifying the list it is iterating over**. – OldCurmudgeon Feb 02 '18 at 14:09
  • *How can the second loop be executed while the first is still iterating?* what is the use case behind this question ? – Ravi Feb 02 '18 at 14:10
  • 2
    you cannot modify a list while looping through that list. – isaace Feb 02 '18 at 14:10
  • for(String s : lista) internally use iterator. and you are access and inserting at same time that it is throwing ConcurrentModificationException – Md Ayub Ali Sarker Feb 02 '18 at 14:20
  • 1
    The 2nd loop itself is the problem. Even if you remove the first loop from your code you will still get ConcurrentModificationException. – isaace Feb 02 '18 at 14:35
  • 1
    Think about it, if you wouldn't get an exception you would end up with an infinite loop because you are adding to your list whatever is in your list and your list keeps in growing. – isaace Feb 02 '18 at 14:42
  • LOL thank you @isaace ! now all is clear!!!!!! I thought the problem was the combination of two loop in cascade! ndr – resla95 Feb 02 '18 at 14:45
  • You are welcome. – isaace Feb 02 '18 at 14:50
  • When you assume that the problem is connected to both loops, it should take less than a minute to disprove yourself by just running the code two times with either loop without the other. Isolating the problem by testing before drawing any conclusions should become your standard procedure. Besides that, I’ll recommend reading [“When to use LinkedList over ArrayList?”](https://stackoverflow.com/q/322715/2711488)… – Holger Feb 02 '18 at 16:02

2 Answers2

2

The for (Element e: list) construct internally uses an Iterator<Element>, which explains your ConcurrentModificationException.

See here for instance:

The compiler does [create the Iterator] for you behind your back, but you need not concern yourself with it.*

--> you actually do need to concern yourself with it, if you intend to modify the stucture while iterating over it.

*Content between square brackets replaced by me for clarity.

Mena
  • 47,782
  • 11
  • 87
  • 106
  • The question was different. Immagine this scenario: System.out.println("Ciao"); // LINE 1 System.out.println("HI"); // LINE 2 The line 2 can't be executed if JVM dont execute before the line 1. So why i shoud worry about the second loop, if it will be executed after the read of list? – resla95 Feb 02 '18 at 14:29
  • And btw if i use an iterator like this : for( Iterator iterator = lista.iterator(); iterator.hasNext()){ lista.add(s); }} The code will run fine – resla95 Feb 02 '18 at 14:30
  • Of course changing the second loop to use an iterator works although you're adding each element again which seems...odd. Have you actually understood any of these answers? – adamcooney Feb 02 '18 at 14:40
2

The problem with second is you are adding new elements. However in the first you just reading.

Imagine the case, you keep counting books and someone inserting book in middle. How irritating ? Without inserting new books, no matter how many times you read it, the result won't change.

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307