aspose file tools*
The moose likes Beginning Java and the fly likes Implementing Iterator problem - ConcurrentModificationException Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Implementing Iterator problem - ConcurrentModificationException" Watch "Implementing Iterator problem - ConcurrentModificationException" New topic
Author

Implementing Iterator problem - ConcurrentModificationException

Neil Veebrun
Greenhorn

Joined: Dec 09, 2011
Posts: 2
Hi there,

I'm fairly new to programming. I was hoping for some help understanding where I might be going wrong when I inherit from Iterator to make a "safe" iterator, please. This is one that can be used by a client object to iterate through the collection, but not remove anything from it.

When I run my program, I get a ConcurrentModificationException as the Client object's printProducts() method is called and I'm not sure why. Here is the relevant code:



And this is the exception:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:782)
at java.util.ArrayList$Itr.next(ArrayList.java:754)
at SafeIterator.next(SafeIterator.java:11)
at SafeIterator.next(SafeIterator.java:1)
at Client.printProducts(Client.java:16)
at Client.<init>(Client.java:8)
at Main.main(Main.java:8)

Help much appreciated.

Thanks,

Neil
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3649
    
  17

Hi Neil. I don't know exactly where it's causing the exception, but I do know you're doing something important wrong, and fixing it might solve your problem.

When you call the iterator() method on an Iterable, it should return a new iterator every time, that will iterate over every element in the Iterable. Instead, you have one iterator, which you return every time. You should first deal with this issue.

Tip: When posting exceptions, make sure the line numbers it refers to match the code you post. So when you have separate source files, post them in separate [code] blocks.
Neil Veebrun
Greenhorn

Joined: Dec 09, 2011
Posts: 2
Hi Stephan,

Thanks for the helpful and quick reply. Your advice to return a new iterator every time on the iterator() method has fixed the problem. I no longer get an exception.

Cheers,

Neil
Praveen Kumar M K
Ranch Hand

Joined: Jul 03, 2011
Posts: 256
Hi Neil,

Welcome to the ranch! (I know am only a few posts old, but hey, couldn't resist )

I can explain to you what a ConcurrentModificationException is, but your program is incomplete, so I can only guess which part of it is giving you the exception. Do post a simple runnable example next time around.

Concept - Once you've created an iterator for a list, it is against the rules of Java to modify the list. When you do so, you get an exception called ConcurrentModificationException. By modification, I mean addition or deletion of the items of the list and not the state of the objects inside the list.

Example :



Please go through this post - ConcurrentModificationException and do tell me if you can figure out where the error is occurring.

Thanks,
Praveen.


Praveen Kumar M K
Ranch Hand

Joined: Jul 03, 2011
Posts: 256
I have a question regarding this topic, will appreciate any help.

What is the need for ConcurrentModificationException exception? I'll approach the question in 3 ways :

1) Iteration is a pattern wherein you sequence through a collection without paying heed to the underlying structure of the collection. At the current iteration pointer, if hasNext() returns a true, you can either use next() or remove() methods and return valid values, else if false, the methods can return null values.(without throwing an exception).

2) The addition and removal of items of a list are independent operations which have nothing to do with the iterator. The exception only shows that there is coupling between these independent entities which am sure is undesirable.

3) Isnt it a programmer's duty to take care that the iterator is sort of "reloaded" or "refreshed" everytime there is a change in the underlying list.(The jvm libraries could also do this automatically).

Please do tell me if I've missed out a concept in Iterator pattern.

Thanks.
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

Barney Balboa wrote:1) Iteration is a pattern wherein you sequence through a collection without paying heed to the underlying structure of the collection. At the current iteration pointer, if hasNext() returns a true, you can either use next() or remove() methods and return valid values, else if false, the methods can return null values.(without throwing an exception).

Iterators are supposed to provide us a sequence through the collection, as if it was a snapshot taken at the time when the iterator was created. Hence, any modification to the underlying collection is not handled by guessing what could be the right behaviour. Think about this - there is a list with 10 elements, and you are iterating through it. You have reached to the last element and another thread inserts a value somewhere in between. Now, should the hasNext() return true (because now there is an element which is not yet visited) or false (because originally the list didn't have this new element when the iterator was created). You can argue about these cases, but the condition soon becomes very complex when there are Sets with various sequencing of elements, and insertion or removal of an element during the iteration makes it impossible to guess whether it would be correct to cater for the change or not.

Hence, as a coherent, consistent mechanism, iterators are designed to be fail-fast. This means, that if the collection has been modified during the iteration, and hasNext() or next() is invoked again, they will throw this exception. Please note that it is not the modification of the collection which results in the exception, but the call to hasNext() or next() after the modification.

Barney Balboa wrote:2) The addition and removal of items of a list are independent operations which have nothing to do with the iterator. The exception only shows that there is coupling between these independent entities which am sure is undesirable.

I would argue that iterator does get affected by modifications on the underlying data structure, as it does not create an in-memory snapshot of the data-structure within itself, when created. Instead, it relies on the data-structure to be consistent till it's iteration is finished.

Barney Balboa wrote:3) Isnt it a programmer's duty to take care that the iterator is sort of "reloaded" or "refreshed" everytime there is a change in the underlying list.(The jvm libraries could also do this automatically).

It is of course a programmer's duty. And this is why ConcurrentModificationException is a RuntimeException, so the users of your API (other programmers) don't have to catch it.
Praveen Kumar M K
Ranch Hand

Joined: Jul 03, 2011
Posts: 256
Thanks for the reply Aditya!

Your explanations make sense. I'll just add one more thing on this and leave it at that. ArrayIndexOutOfBounds is an exception wherein there is an actual mistake committed from the programmer's end, but modifying a collection didnt seem to attribute to a mistake and that is what made me think the use of ConcurrentModificationException.

I verified your statement in bold and that's absolutely correct. I'll post a few more questions on the same, so please bear with me

What actually happens when the subsequent iterator operation is called? I mean how does the iterator get to know that there has been a change in the list.
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3649
    
  17

The data structure simply holds some field containing the amount of modifications that happened to it since it came into existence. When the iterator starts, it records this field, and on each step it checks whether the field still has the same value. If not, a modification occurred during the iteration, and the iterator will throw the exception.
Praveen Kumar M K
Ranch Hand

Joined: Jul 03, 2011
Posts: 256
Yes...A simple check on modification to the size of the collection would do I guess.

Thank you very much for all your replies
 
Consider Paul's rocket mass heater.
 
subject: Implementing Iterator problem - ConcurrentModificationException