为什么ArrayList remove报错

 

不报错

List<String> userNames = new ArrayList<String>() {{
    add("Hollis");
    add("hollis");
    add("HollisChuang");
    add("H");
}};

for (int i = 0; i < userNames.size(); i++) { // 每一次循环都会重新计算当前的size, 从而i不会越界
    if (userNames.get(i).equals("Hollis")) {
        userNames.remove(i);
    }
}

System.out.println(userNames);

 

会报错 ConcurrentModificationException

List<String> userNames = new ArrayList<String>() {{
    add("Hollis");
    add("hollis");
    add("HollisChuang");
    add("H");
}};

for (String userName : userNames) {
    if (userName.equals("Hollis")) {
        userNames.remove(userName);
    }
}

System.out.println(userNames);

 

 

 通过查看源码发现,引起异常是因为modCount和expectModCount不一致导致的

final void checkForComodification() {
    // modCount 和 expectedModCount 不同导致的
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
}

 

 

通过remove方法的源码发现 remove 调用 fastremove, fastremove中只是修改了modCount, 造成了两者的不一致.

private void fastRemove(int index) {
    // 只是修改了modCount
    modCount++;
    // omit code
    elementData[--size] = null; // clear to let GC do its work
}

 

posted @ 2019-03-28 18:59  webglcn  阅读(270)  评论(0编辑  收藏  举报