Wednesday, October 29, 2008

Remove elements in a List safely

As the javadoc for the interface List states, it provides two methods to efficiently remove entries. But when you remove and entry during iteration a ConcurrentModificationException may occur. To avoid this, use the methode remove in the interface Iterator instead of the one in List. But remember, we're talking about interfaces, thefore there is no warranty that the concrete implementation take care of this behaviour.
Anyway with ArrayList you can use Iterator.remove() without problem. See the example
@Before
public void setup() throws Exception {
list = new ArrayList();
int len = 100;
for (int i = 0; i < len; i++) {
list.add(i);
}
}

@Test(expected = ConcurrentModificationException.class)
public void removeWrong() throws Exception {
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Integer i = iterator.next();
if (i >= 50) {
// wrong can throw ConcurrentModificationException
list.remove(i);
}
}
}

@Test
public void removeRight() throws Exception {
Assert.assertEquals(100, list.size());
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Integer i = iterator.next();
if (i >= 50) {
iterator.remove();
}
}
Assert.assertEquals(50, list.size());
}

Also if you synchronize the list with List list = Collections.synchronizedList(new ArrayList(...));, it will throw a ConcurrentModificationException.

No comments: