过滤 Java lambda 中的集合 w/o 创建新集合

filter Java collection in lambda w/o creating new one

我在 Java 中有一个最终的 ConcurrentMap,我想在不创建新元素的情况下过滤它的元素。

问题是:我可以从 lambda 中引用集合 (people) 吗?

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

.keySet().values().entrySet() return 分别是地图键、值和条目的实时视图。您可以从这些集合中删除元素,相应的条目将从地图中删除:

people.keySet().removeIf(name -> name.length() > 3);

最近才讨论过这个问题,例如

文档指出 CHM 提供 弱一致性遍历 ,而不是 快速失败遍历 ;如所见 here 这是什么意思:

they may proceed concurrently with other operations

they are guaranteed to traverse elements as they existed upon construction exactly once, and may (but are not guaranteed to) reflect any modifications subsequent to construction.

通常 CHM 更改其结构的操作是线程安全的,但 Stream 文档仍然不鼓励您想要实现的目标。这称为干扰,应该避免。如果您使用简单的 HashMap 更改该结构,您将得到 ConcurrentModificationException,因为您在遍历它的同时修改了源代码。除非您有令人信服的理由不丢弃以前的地图,否则您应该只过滤您感兴趣的值并收集它们。

您还可以看到当您从上面的 link 中 添加 CMH 时如何获得意想不到的结果。