maoruibin / maoruibin/maoruibin.github.com

为什么使用 Iterator 可以在遍历时删除元素而不报错

Open
#56 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

深度思考
Dominant language
HTML
Stars
22
Forks
4
PR merge metrics
No merged PRs in 30d

Description

List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("9");
list.add("3");
list.add("4");
list.add("5");
list.add("6");

// 正常 for 循环迭代删除 9 这个元素 报错
for(String item:list){
    if("9".equals(item)){
        list.remove(item);
    }
}

//使用迭代器删除 9  正常
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
    if ("9".equals(iterator.next())) {
        iterator.remove();
    }
}

使用正常的 for 循环遍历 list 报错如下所示

image

具体报错的代码在 list 中如下所示:

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

这里因为修改次数跟期望修改次数不一致所以奔溃了。

其中 modCount 是指 list 被修改的次数,这个数字会在 list 执行 add、remove 等操作时都会改变,而 expectedModCount 默认不会改变, list 在执行遍历时会调用 checkForComodification 方法进行检查,此时如果发现两个数值不一样就会 crash。

如何避免这个错误呢,其实想想也比较简单,就是在执行 add 或者 remove 时让 expectedModCount 跟 modeCount 保持一致即可,但是 list 的这两个方法中只会修改 modCount,不会修改 expectedModCount,所以不行。

现在回到文章的标题,为什么使用 iterator 就可以,因为 iterator 的 remove 方法在执行时,不仅调用了 list 的 remove ,还修改了 expectedModCount。

image

如上所示,所以用 iterator 执行迭代时可以执行删除操作,而不会报异常。

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is named. Start by running the Java example from the issue and reading the shown ArrayList and Iterator behavior; done means the blog content clearly explains why iterator removal is allowed while direct list removal during traversal triggers the exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.