Friday, 11 June 2010

Handling Concurrent Modification Exceptions in Java Collections

Today we have faced below problem when trying to remove a object from a list


Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
at java.util.AbstractList$Itr.next(AbstractList.java:420)
at ConcurrentModificationException.removeObjectTwo(ConcurrentModificationException.java:28)
at ConcurrentModificationException.main(ConcurrentModificationException.java:20)



Below is the code


public class ConcurrentModificationException
{

public static void main(String[] args)
{

A a=new A("sneha","prasanth");
A a1=new A("pradeep","hima");
A a2=new A("praveen","subz");

List<A> list=new ArrayList<A>();
list.add(a);list.add(a1);list.add(a2);

B b=new B();
b.setAList(list);

removeObjectTwo(b,a1);

System.out.println(b.getAList());

}

private static void removeObjectTwo(B b,A aToBeRemoved){

for(A a : b.getAList()){
b.removeA(a);
}
}
}

class B {

private List<A> aList=new ArrayList<A>();

public List<A> getAList()
{
return aList;
}

public void setAList(List<A> list)
{
aList = list;
}

public void removeA(A a) {
aList.remove(a);
a.delete();
}
}

class A {

private String firstName;
private String lastName;
private String isDeleted="N";

A(String firstName,String lastName) {
this.firstName=firstName;
this.lastName=lastName;
}

public String getIsDeleted()
{
return isDeleted;
}
public void setIsDeleted(String isDeleted)
{
this.isDeleted = isDeleted;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}

public void delete() {
this.isDeleted="Y";
}

public String toString() {
return firstName + ":" + lastName;
}

}



Once you have changed the below method it works perfectly


private static void removeObjectTwo(B b,A aToBeRemoved){

List<A> dupA=new ArrayList<A>();

for(A a : b.getAList()){
if(aToBeRemoved.equals(a))
dupA.add(a);
}

for (A a : dupA)
{
b.removeA(a);
}

}
}



Lesson: Never try to do both read/write on the same collection object and better try to take 2 seperate lists and do the way it was done as shown in the above code.

No comments: