在lambda中过滤Java集合而不创建新的集合

时间:2017-06-08 04:22:20

标签: lambda java-8 concurrenthashmap

我在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);
});

2 个答案:

答案 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时,您还可以看到如何获得意想不到的结果。