我在Java中有一个最终的ConcurrentMap,想要在不创建新元素的情况下过滤它的元素。
问题是:我可以从lambda中引用集合(人)吗?
final ConcurrentMap<String, String> people = new ConcurrentHashMap<>();
people.put("Sam", "developer");
people.put("Kate", "tester");
people.forEach((name, role) -> {
if (name.length() > 3)
people.remove(name);
});
答案 0 :(得分:3)
.keySet()
,.values()
和.entrySet()
分别返回地图的键,值和条目的实时视图。您可以从这些集合中删除元素,相应的条目将从地图中删除:
people.keySet().removeIf(name -> name.length() > 3);
答案 1 :(得分:3)
最近刚讨论过这种情况,例如here。
文档指出CHM
提供弱一致遍历,而不是 fail-fast traversal ;如图所示here这意味着什么:
他们可能与其他操作同时进行
它们可以保证遍历元素,因为它们在构造时只存在一次,可能(但不保证)反映构造后的任何修改。
通常CHM
操作改变它的结构是线程安全的,但Stream文档仍然不鼓励你想要实现的目标。这称为干扰,应该避免。如果您使用简单的HashMap
更改该结构,则会获得ConcurrentModificationException
,因为您在遍历它时修改了源代码。除非您有令人信服的理由不放弃以前的地图,否则您应该只过滤您感兴趣的值并收集它们。
当您从上面的链接添加到CMH
时,您还可以看到如何获得意想不到的结果。