2

The following code crashes(Concurrent modification exception) in JVM but not in DVM, i am unable to understand why its not crashing in andorid. I am using JB

    List<String> list = new ArrayList<String>();
    list.add("Something");//add only 1 object

    for(String a:list){
        list.remove(a);
    }
Ankit Khare
  • 99
  • 2
  • 11
  • The fact that is crashes in a JVM is evident : Use an iterator to remove an element from a collection while iterating on it. The implementation of Iterator might be different on DVM. That said, use an iterator and it will work on both. – Arnaud Denoyelle Mar 07 '14 at 09:25
  • see: http://stackoverflow.com/questions/5051879/in-java-how-can-this-throw-a-concurrentmodificationexception-in-a-single-threade?rq=1 – Daniel L. Mar 07 '14 at 09:35
  • I understand its a different behaviour on DVM , but didnt understand why so! Though fail-fast is JVM dependant but still, i expected it to be basic behaviour – Ankit Khare Mar 10 '14 at 10:10

3 Answers3

1

You are iterating the list as well as trying to remove the value from the same list. This causes the Exception. Try adding the items to be removed in a separate list and after the iteration use List.removeall() function to remove all the unwanted values.

Sample:

List<String> removeList = new ArrayList<String>();
for(String a:list) {
removeList.add(a);
}

list.removeAll(removeList);
Sandeep
  • 712
  • 1
  • 10
  • 22
1

Hi yes it will give an exception as

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at coffee.CoffeeApp.main(CoffeeApp.java:20)
Java Result: 1

because

fail-fast behavior is implemented by keeping a modification count and if iteration thread realizes the change in modification count it throws ConcurrentModificationException.

so do something like this and iterate over list with the help of Iterator

List<String> list = new ArrayList<String>();
list.add("Something");//add only 1 object

Iterator<String> it = list.iterator();
while(it.hasNext()) {
    it.next();
    it.remove();
    //Do something with obj
}

what we can say is the fail-fast behavior of an iterator cannot be guaranteed as it is, here an unsynchronized concurrent modification is there. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, fail-fast Iterators fail as soon as they realized that structure of Collection has been modified since iteration has begun and if the iterator thread realizes the modification ,then it throws ConcurrentModificationException. Changes can be additions, updation or deletion.

In android may be it is under different implementation so not having a problem.

for a comparison study please visit however i did not had a great R&D here

http://www.docjar.com/html/api/java/util/ArrayList.java.html

v/s

https://android.googlesource.com/platform/libcore/+/f33eae7e84eb6d3b0f4e86b59605bb3de73009f3/luni/src/main/java/java/util/ArrayList.java

Jitesh Upadhyay
  • 5,244
  • 2
  • 25
  • 43
0

While you're iterating over a List (or any Collection, for that matter), you can only modify the List through the very same Iterator. So this will work:

for(Iterator<String> listIter = list.iterator(); listIter.hasNext();) {
    listIter.next().remove();
}
Ray
  • 3,084
  • 2
  • 19
  • 27