Getting a ConcurrentModificationException thrown w

2019-01-01 01:16发布

@Test
public void testListCur(){
    List<String> li=new ArrayList<String>();
    for(int i=0;i<10;i++){
        li.add("str"+i);
    }

    for(String st:li){
        if(st.equalsIgnoreCase("str3"))
            li.remove("str3");
    }
    System.out.println(li);
}

When I run this code,I will throw a ConcurrentModificationException.

It looks as though when I remove the specified element from the list,the list does not know its size have been changed.

I'm wondering if this is a common problem with collections and removing elements?

11条回答
时光乱了年华
2楼-- · 2019-01-01 01:37

I believe this is the purpose behind the Iterator.remove() method, to be able to remove an element from the collection while iterating.

For example:

Iterator<String> iter = li.iterator();
while(iter.hasNext()){
    if(iter.next().equalsIgnoreCase("str3"))
        iter.remove();
}
查看更多
泪湿衣
3楼-- · 2019-01-01 01:37

You could make a copy of list you want to remove element from, directly in for-each loop. For me, that is the simpliest way. Something like this:

for (String stringIter : new ArrayList<String>(myList)) {
    myList.remove(itemToRemove);
}

Hope that will help you..

查看更多
情到深处是孤独
4楼-- · 2019-01-01 01:42

ArrayList has field modCount - count of collection modifications

When you invoke method iterator() creates new object Itr. It has field expectedModCount. expectedModCount field initialize by modCount value. When you invoke

li.remove("str3");

modCount increments. When do you try access to li via iterator checks that expectedModCount == modCount

and if it is false throws ConcurrentModificationException

Hence if you get iterator and after collection modified - iterator is considered not valid and you cannot use it.

查看更多
笑指拈花
5楼-- · 2019-01-01 01:45

I think it is worth mentioning the Java 8 version

@Test
public void testListCur() {
    List<String> li = new ArrayList<String>();
    for (int i = 0; i < 10; i++) {
        li.add("str" + i);
    }

    li = li.stream().filter(st -> !st.equalsIgnoreCase("str3")).collect(Collectors.toList());

    System.out.println(li);
}
查看更多
怪性笑人.
6楼-- · 2019-01-01 01:48

Try this (Java 8):

list.removeIf(condition);
查看更多
登录 后发表回答