java - 知道为什么我在从 HashMap 中删除键时没有收到 java.util.ConcurrentModificationException 吗?

标签 java hashmap concurrentmodification

我想要实现的是,如果 key 是要删除的 key。将 key 更改为当前时间,但其值应该相同。

我的代码片段是:

public class hello
{
    private static HashMap<String,String> fileMap;
    private static final String KEY_REMOVED = "d";
    static {
        fileMap = new HashMap<String, String>();
        fileMap.put("a", "hello");
        fileMap.put(KEY_REMOVED, "bye");
        fileMap.put("c", "hi");
    }

    public static void main(String []args){
        upload();
}

    private static void upload() throws  ConcurrentModificationException {

        for (Map.Entry<String, String> entry : fileMap.entrySet()) {
            System.out.println("Uploading key " + entry.getKey());

            String fileName = entry.getKey();

            if (fileName.equals(KEY_REMOVED)) {
                fileName = new Timestamp(System.currentTimeMillis()).getTime();
                String temp2 = fileMap.remove(VIDEO_MP4_ASSET);
                System.out.println("hashmap after removing key is " + fileMap);
                System.out.println("adding  key to hashmap " + fileName);
                fileMap.put(fileName, temp2);

            } else {

                System.out.println("continue");
            }
            System.out.println("hashmap is " + fileMap);
        }
    }

理想情况下,在删除 key 时我们应该得到 ConcurrentModificationException。我担心我现在没有得到它。但是我的代码稍后可能会崩溃。是吗?

最佳答案

这可能有点令人困惑,因为 Javadoc 首先声明了

The iterators returned by all of this class's "collection view methods" (values(), keySet(), entrySet()) are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.

Note that the fail-fast behavior of an iterator cannot be guaranteed

但它也指出 HashMap.entrySet()

Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined.

现在未定义确实包括抛出ConcurrentModificationException ,但有many cases没有抛出它,因为如开头所示,无法保证快速失败行为。

因此,如果您要迭代 keySet() , values()entrySet()并且您正在修改 Map结构上,即remove()put使用新 key (不替换现有 key 的值),您可能会得到:a ConcurrentModificationException或者迭代时发生奇怪的事情,例如跳过元素或遇到元素两次。

关于java - 知道为什么我在从 HashMap 中删除键时没有收到 java.util.ConcurrentModificationException 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60103827/

相关文章:

java - 从 HashMap 中只打印一个对象

java - Hashmap的实现

用于并发映射修改的类似 Java 迭代器的构造

java - 生命周期配置未涵盖 Maven 插件执行

java - mysqldump(错误代码 : 2) trying do backup from java in linux (server) with wildfly

java - Java中通过编码将char转换为十六进制

java - 从 CSV 读取长数据

java - 在 TreeMap、HashMap 或 LinkedHashMap 中存储具有重复键的值

java - 不修改对象的 ConcurrentModificationException

java - foreach 循环中的 ConcurrentModificationException