【问题标题】:How to remove a key from HashMap? [duplicate]如何从 HashMap 中删除一个键? [复制]
【发布时间】:2015-12-28 21:56:20
【问题描述】:

我有这个哈希图

HashMap <Integer,Integer> H = new HashMap <Integer,Integer>();

当我尝试从 HashMap 中删除密钥时,我收到此错误

**Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:922)
at java.util.HashMap$KeyIterator.next(HashMap.java:956)
at Livre.montantTotal(Livre.java:42)** 

这是我的代码

for (int e : H.keySet()){
    H.put(e, H.get(e)-1);
    if (H.get(e) == 0){
        H.remove(e);
    }
}   

【问题讨论】:

  • 您不能在迭代时修改集合。
  • 好吧,您可以在迭代器上使用 remove() 方法(因此将 for 循环扩展为适当的迭代器),但在迭代时您将无法添加到集合中。也许收集列表中的添加并添加到最后。
  • @FernandoMatsumoto 嗯,它是相关的,但不是真正重复的,因为这是一张地图
  • 为什么每个人都投票反对?它可能是重复的,但它是一个常见问题

标签: java hashmap


【解决方案1】:

您收到此错误是因为您尝试删除该元素并重新排列已在使用中的哈希图(在循环中)。

要遍历 Java 中的集合对象,您有一个 Iterator 类可以解决您的问题。该类有一个remove() 方法可以从HashMap 中删除一个密钥对值。

How to remove a key from HashMap while iterating over it?
iterating over and removing from a map 可能重复

编辑:

在 Java 7 及更早版本上试用此代码:

Map<String, String> map = new HashMap<String, String>() {
  {
    put("test", "test123");
    put("test2", "test456");
  }
};

for(Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); it.hasNext(); ) {
  Map.Entry<String, String> entry = it.next();
  if(entry.getKey().equals("test")) {
    it.remove();
  }
}

在 Java 8 中,你可以试试这个:

map.entrySet().removeIf(e-> <boolean expression> );

【讨论】:

  • 赞成,因为您不能发表评论,但如果您有足够的代表,这应该是评论。如果您包含完整的答案而不仅仅是指向其他问题的链接,那将是一个更好的答案
  • Java 8 的添加非常棒,因为这是人们需要了解的 Map API 最近的良好变化之一。值得告诉你改进你的答案,并支持你:)
【解决方案2】:

您需要使用 Iterator 在迭代集合时从集合中删除。

for (Iterator<Map.Entry<Integer, Integer>> i = H.entrySet().iterator(); i.hasNext();) {
    Map.Entry<Integer, Integer> e = i.next();
    int v = e.getValue();
    if (v == 1)
        i.remove();
    else
        e.setValue(v - 1);
}

来自HashMap.EntrySet() (https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html) 的文档

该集合由地图支持,因此对地图的更改会反映在 集合,反之亦然。

【讨论】:

  • 认为引用文档以证明更改将反映到地图上很有用。一开始这不是那么微不足道
  • @Dici 我现在会尝试找到相关位。
【解决方案3】:

在迭代过程中无法更改某些内容。当您更改HashMap 时,您也将其更改为keySet,并且由于您正在迭代它,Java 会引发错误。您可能需要做的是将需要删除的每个键添加到单独的列表中,然后遍历该列表。

像这样:

ArrayList<Integer> otherList = new ArrayList<>();
for(int e : H.keySet()){
    h.put(e, H.get(e) - 1);
    if(H.get(e) == 0)
        otherList.add(e);
}

for(int e : otherList){
    H.remove(e);
}

【讨论】:

  • 根据文档,可以使用Iterator.remove从集合中删除项目,并且更改将反映到地图上。我不认为这是线程安全的
  • 无论如何,线程安全性不亚于从多个线程修改映射。
猜你喜欢
  • 2019-06-26
  • 2011-08-30
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
相关资源
最近更新 更多