为什么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
}

猜你喜欢

转载自www.cnblogs.com/webglcn/p/10616994.html