繁体   English   中英

ConcurrentHashMap的迭代器给出奇怪的结果

[英]Iterator for ConcurrentHashMap giving strange result

ConcurrentHashMap是线程安全的。 因此,如果在迭代时添加任何要映射的值,则不应考虑它们。 下面是我的代码:

public class Test {
public static void main(String[] args) {
    ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();
    map.put("ONE", 1);
    map.put("TWO", 2);
    Iterator<String> it = map.keySet().iterator();
    while (it.hasNext()) {
        String key = (String) it.next();
        System.out.println(key + " : " + map.get(key));
        map.put("9", 10); // This should not be reflected in the Iterator
        map.put("5", 10); // This should not be reflected in the Iterator
    }
}
}

输出:

    TWO : 2
    ONE : 1
    9 : 10

我的问题是为什么迭代器考虑map.put(“ 9”,10);?

ConcurrentHashMap是线程安全的。 因此,如果在迭代时添加任何要映射的值,则不应考虑它们。

那是不对的。 这是javadoc所说的:

“类似地,迭代器,拆分器和枚举返回在创建迭代器/枚举时或此后某个时刻反映哈希表状态的元素。”

注意“或自”!

它还表示迭代器“弱一致性”,这意味着:

“保证它们会遍历在构造时已经存在的元素一次,并且可能(但不保证)反映出构造后的任何修改。”


简而言之,您期望的是Javadocs显然没有的迭代器的属性。

ConcurrentHashMap是线程安全的 ,但这是另一种情况。

一个列表,你可以使用带有ListIterator.Add这是专为的ListIterator。

使用HashMap,我看到两个解决方案:

  1. 转换为列表,然后返回到HashMap

  2. 循环结束后,对新元素使用附加的HashMap,然后使用另一个循环添加所有新元素(虽然不太优雅,但是可以!)。

对于Java 8,您可以考虑使用lambda-expressions来简化代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM