• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Concurrent Modification Exception

 
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I want to iterate a list and at the same time modify it. List contains object of Strings.
But it is throwing Concurrent Modification Exception . Please tell me to solve this problem.
 
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The javadoc API explains the causes of the problem

...it is not generally permissible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some Iterator implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. Iterators that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future.



You could use another ways to iterate and modify your list instead of iterator. For instance the List interface offer the get(index) and the set(index,value) methods.

Another thing you must keep in mind is the importance of synchronizing access to your collection, at least using Collections.synchronizedList(List list).

[ October 06, 2006: Message edited by: Edwin Dalorzo ]
[ October 06, 2006: Message edited by: Edwin Dalorzo ]
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Manoj --

Most of the time if someone wants to iterate and modify a list at the same time, it's to inspect all the elements and remove some of them. Note that the Iterator interface has a remove() method which removes the current element (the last one returned by "next()".) Not all Iterators implement remove(), but many in the Collections API do. If you use Iterator.remove() to remove your elements, there will be no ConcurrentModificationException.
 
Manoj Raghuwanshi
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for help.
What I'm thinking is - while iterating over the list, inspect the objects and copy those objects in to another list. Then remove this list from the original by using List.removeAll(Collection c).
 
Ranch Hand
Posts: 1970
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Manoj Raghuwanshi:
Thanks for help.
What I'm thinking is - while iterating over the list, inspect the objects and copy those objects in to another list. Then remove this list from the original by using List.removeAll(Collection c).



You could do that, but why not use the Iterator.remove() method, like the wise EF-H says?
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the exception just happens if the list is modified before you finish to use the iterator. For instance the following code will produce ConcurrentModificationException.



But this code would not:



Ernest's suggestion is that you use a ListIterator and use the remove method. Like this

 
Manoj Raghuwanshi
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry please ignore my previous comment of sorting out the objects in to another list and then use List.removeAll() because that dont work. Let me explain my requirement-
My program :-

List list =getList(); // A method that will return a list of Integer //objects [1,2,3,4]

for(int i=0;i<list.size();i++){
Object temp=list.get(i);
If(temp instanceof Integer){
Integer id=(Integer) temp;
// Business logic to get parent-attachment document numbers for this id
//if those ids present in this list remove at this point from the underlying //list , here I cant do because in that case I cant use for loop to iterate //I must use iterator and that will throw concurrent modification //exception. So mark these documents as String.
List paList=getParentAttachment(id);
for(int j=0;j<paList.size();j++){
Integer doc=(Integer) paList.get(j);
if(list.contains(doc)){
int position=list.indexOf(doc);
list.remove(position);
list.add(position,"String");
}
}
}
}
// Remove all string objects from list
Iterator it=list.iterator();
while(it.hasNext()){
Object obj=it.next();
if(obj instanceof String)
it.remove();
}


I know this is crud but i dont see any other solution, may be a design pattern?
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, at first sight, it appears that your code will not produce ConcurrentModificationException.

I may be work, but your second inner loop seems to look for integers in the list and then replace them with a String object, and at the end, you remove all Strings from the list.

I cannot say that is bad, but why do you add a String to the list if you prented to delete it right after inserted it?
 
Manoj Raghuwanshi
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because in for loop
for(int i=0;i<list.size();i++) , list.size() will return the initial size of the list and inside this for loop if I remove any object using list.remove(index) , the list will throw ArrayIndexOutOfBound Exception.I am replacing the Integer objects at that position in the list with String object so List size remain the same throughout the iteration of the for loop.
 
Edwin Dalorzo
Ranch Hand
Posts: 961
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What if instead of removing the object while iterating your list, you add your findings to another list, named itemsToBeRemoved, then at the end of the loop you simple remove your findings with list.removeAll(itemsToBeRemoved)?
 
But how did the elephant get like that? What did you do? I think all we can do now is read this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic