迭代器如何同时从集合中读取和删除元素?

How does the iterator simultaneously read and delete elements from a collection?

我创建了以下代码。 我的 objective 是检查在读取集合时使用迭代器删除元素。 任何人都可以解释为什么在将 hashmap 的值集合添加到链表并为该列表创建迭代器后抛出 concurrentModificationException,但在将集合添加到列表后获得迭代器时不会抛出相同的异常?

我知道原因很简单,想要一些容易获得的东西,但我只是想确认我的想法是否正确。

还有2点。 1. 由于 hashmap 不是线程安全的,所以为什么我们不能在迭代器读取时向它添加任何元素? 2. 如果是,那么我们如何从地图中删除元素?

 package com.Users;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;

    public class Temp{
        public static void main(String arg[]){
            HashMap<String, String> map=new HashMap();
            map.put("A", "B");
            map.put("C", "D");

            LinkedList<String> list=new LinkedList<>();

            //****** concurent exception is thrown when ever line 1 is swapped with line 2 ******
            Iterator<String> iterator=list.iterator();  //line no. 1
            list.addAll(map.values());    //line no. 2
            //******************

            while(iterator.hasNext()){
                if(iterator.next().equals("B")){
                    iterator.remove();
                }
            }


            System.out.println(list);
        }
    }

HashMap 上的迭代器本质上是 fail-fast,这实质上意味着它们会尽快中止操作,并立即暴露失败。

集合维护一个名为 modCount 的内部计数器。每当从集合中添加或删除项目时,此计数器都会被修改。

迭代时,在每次调用 next() 时,会将 modCount 的当前值与初始值进行比较。如果不匹配,它会抛出 ConcurrentModificationException 中止整个操作。


  1. As hashmap is not threadsafe, so is it why that we can't add any element to it while the iterator is reading?

我们无法修改集合,因为我们正在迭代集合,因为大多数集合(例如 ArrayList、HashMap)默认具有快速失败的迭代器。


  1. If yes, then how are we able to remove elements from the map?

我们能够删除您示例中的元素,因为我们在 iterator.remove() 中使用了迭代器的 remove() 方法。 如果我们使用集合的 remove() 方法,这也会抛出 ConcurrentModificationException

请阅读 this 以获得详细说明。