Java :在 ConcurrentHashMap 中,如果更改键,为什么会有不同的输出

Java : In ConcurrentHashMap , why is having differnet output if i changes the key

第一次迭代:-

class ConcurrentHashMapBehaviour
{       
    public static void main(String[] args) 
    {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
        map.put("ONE", 1);
        map.put("TWO", 2);
        map.put("THREE", 3);
        map.put("FOUR", 4);
        Iterator<String> it = map.keySet().iterator();
        while (it.hasNext()){
            String key = (String) it.next();
            System.out.println(key+" : "+map.get(key));
            map.put("SEVEN", 7);
        }
    }
}

输出为:

ONE : 1
FOUR : 4
TWO : 2
THREE : 3
SEVEN : 7

更改密钥后的第二次迭代

class ConcurrentHashMapBehaviour
{       
    public static void main(String[] args) 
    {
        ConcurrentHashMap<String, Integer> map = new 
        ConcurrentHashMap<String, Integer>();

        map.put("ONE", 1);
        map.put("TWO", 2);
        map.put("THREE", 3);
        map.put("FOUR", 4);
        Iterator<String> it = map.keySet().iterator();
        while (it.hasNext()){
            String key = (String) it.next();
            System.out.println(key+" : "+map.get(key));
            map.put("FIVE", 5);
        }           
    }
} 

输出为:

ONE : 1
FOUR : 4
TWO : 2
THREE : 3

所以我的问题是,为什么第一次迭代将 7 个作为输出,而在第二次迭代中不包括 5 个?

Javadoc(我强调):

Similarly, Iterators, Spliterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.

换句话说,对于迭代器可用的视图没有任何保证。在创建 Iterator 之后,它可能知道也可能不知道地图的更改。唯一的保证是

They do not throw ConcurrentModificationException.

当您键入时

Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
{
    String key = it.next();
    System.out.println(key + " : " + map.get(key));
    map.put("FIVE", 5);
}

您可能会在每次打印值时将 ("FIVE", 5) 放入地图,但这不会将其添加到 运行 迭代器。迭代器不更新。事实上,在没有迭代器的情况下更改迭代列表或映射(例如使用 for each-loop)将导致 ConcurrentModificationException.


当您在第一个循环之后执行第二个循环并创建一个新的迭代器时。它还将打印出新值:

Iterator<String> it2 = map.keySet().iterator();
while (it2.hasNext())
{
    String key = it2.next();
    System.out.println(key + " : " + map.get(key));
}

输出:

FIVE : 5
ONE : 1
FOUR : 4
TWO : 2
THREE : 3