遍历并从map中移除重复数据
- 具体问题已经在这个链接回答了
- 如下代码
for (Object key : map.keySet())
if (something)
map.remove(key);
- 程序执行会抛出
ConcurrentModificationException
异常。所以我对上面的代码做了一下修改
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
- 这是实现代码
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();
}
- 事实上你可以使用迭代器来实现删除的功能。这样就不会报错了。因为迭代器对重构没有要求。
个人总结
- 不管是map还是list在循环中是不能够改变结构的。因为在内部是会统计重构的次数的。再循环中如果改变了就会抛出异常。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!