map遍历删除数据报错 | Java Debug 笔记

2023-11-28 15:57:24 浏览数 (1)

遍历并从map中移除重复数据


  1. 具体问题已经在这个链接回答了
  2. 如下代码
代码语言:java复制
for (Object key : map.keySet())
    if (something)
        map.remove(key);
  • 程序执行会抛出ConcurrentModificationException异常。所以我对上面的代码做了一下修改
代码语言:java复制
for (Object key : new ArrayList<Object>(map.keySet()))
    if (something)
        map.remove(key);
  • 当然这段代码是在synchronized 同步块中。
  • 还有更好的方案吗?我们看看评论区是如何回答的。

回答1


  • 这两个方法我并没有看出有什么不同。也许我还是不理解你表达的意思。你可以贴出你的最新的代码吗?
  • 笔者这里也是没有看懂。为什么第二段代码加上同步块就可以不报错了。

回答2


  • 如果你是java8 ,你可以使用map.entrySet().removeIf(e -> <boolean expression>); 来实现你的功能。
  • map.values和map.keySet()同样也都支持这个removeIf方法。
  • removeIf在map.values()上的行为是什么?它删除指向该值的所有key->val元素

回答3


  • 这是实现代码
代码语言:java复制
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();
    }
}
  • 你通过it.remve而不是通过collection.remve这个在循环里还是很明智的。
  • 当然这个前提是你使用的是Java及其以上版本。

回答4


代码语言:java复制
Iterator<Object> it = map.keySet().iterator();

while (it.hasNext())
{
  it.next();
  if (something)
    it.remove();
 }
  1. 事实上你可以使用迭代器来实现删除的功能。这样就不会报错了。因为迭代器对重构没有要求。

个人总结


  • 不管是map还是list在循环中是不能够改变结构的。因为在内部是会统计重构的次数的。再循环中如果改变了就会抛出异常。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞