• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Rob Spoor
  • Henry Wong
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh
  • Jj Roberts

Why I must use iterator.remove() to remove element from my collection?

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

Yes I know what fail-fast iterator is and how does mod count work. Basically it doesn't allow me to change collection while I am iterating it.
But using iterator.remove() I can actually delete an element while iteration.

My question is why I can't simply do it without iterator's remove() method?

For example, why I must do this:

And not like this:


First one works, second one throws ConcurrentModificationException.
Can someone tell me how does it happen when I am doing exactly the same thing (at least from my point of view)?

Thanks!
 
Marshal
Posts: 72406
315
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is how Iterators are designed. While the iterator is in operation, it insists on being the only thing to alter the structure of your Collection. You can remove elements with the other methods of the Collection interface, but only when there aren't any Iterators around. That is why you should always make Iterators local variables. If you can create an Iterator in a for loop, you can restrict its scope to the loop.

And welcome to the Ranch
 
Campbell Ritchie
Marshal
Posts: 72406
315
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was short of time to reply last night, so had to make my reply very brief.

If you make an Iterator a field and instantiate it, it will exist forever and will complain biutterly whenever it notices a “structural alteration” in whichever Collection you are iterating.
You will find more about that in the documentation. I notice that the remove() method changed from being an abstract method (see the Java7 documentation) to a default method. I don't know how much benefit you get from that change; that method has to be overridden in > 90% of cases anyway.
The documentation for ArrayList#iterator() doesn't tell you a lot, but these two links to its supertype might help more 1 2. If I remember correctly, use of clear(), addXXX(), removeXXX(), retainAll(), and sort() alter the List structurally, but (I think) set() doesn't. The XXXstream() methods are not allowed to be implemented so as to alter their source Collection. Also you can only call remove() once per next() call.
The Iterator keeps a count of the modifications in the List; adding 1 for each call to remove(). (A ListIterator has more methods that increment its count.) Similarly the List adds 1 for each alteration. If the Iterator notices a discrepancy between the two counts, it will throw a concurrent modification exception. The conventional way to write an Iterator shown in all the books is like this:-It should read like this:-The additional {...} make the Iterator go out of scope. If you write the following, the Iterator will still be in scope when you call remove(), which can cause a concurrent modification to be detected and an exception to be thrown.There aer idfferent ways to make the Iteratro go out of scope: use a plain for loop:-Or a for‑each loop, which treats its underlying Collectiopn in a “read‑” fashion:--You can of course add and remove things to/rfom Collections without an Iterator; the following plain for loop works well for something supporting random access, e.g. an array list, but doesn't work at all well for a linked list:--I believe that only Lists support a get() method, because only Lists maintain their elements with an index.

[edit]Two spelling corrections.
[Addition]Don't forget: a for‑each loop uses an Iterator in the background.
 
Saloon Keeper
Posts: 12806
278
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The reason why it was designed this way makes sense if you think about it for a minute:

Considider this loop:

This code will remove '3' from the list of digits, but it will print "012356789", skipping the '4'. Does it really make sense that the loop will continue to iterate at index 4 if you've removed the element at index 3? In this case, you would want the loop to repeat the index 3. But how does it make sense that a for-loop that iterates over each index would repeat certain indices?

With an iterator, this confusion doesn't exist. An iterator will not suddenly point to the element at index 4 if you tell it to remove the element at index 3. You explicitly have to call next() first. This ensures that the loop will always do what you expect it to do.
 
Stefan Jankovic
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks people a lot! It is a lot cleaner concept of using iterator for removing things now
 
Campbell Ritchie
Marshal
Posts: 72406
315
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stefan Jankovic wrote:Thanks

That's a pleasure

. . . cleaner concept . . .

Well done getting the concept right
 
I'm full of tinier men! And a tiny ad:
SKIP - a book about connecting industrious people with elderly land owners
https://coderanch.com/t/skip-book
reply
    Bookmark Topic Watch Topic
  • New Topic