当前位置: 首页 > 面试题库 >

使用带有Maps键集的流时发生ConcurrentModificationException

燕光熙
2023-03-14
问题内容

我想删除所有someMap其中没有键的项目someList。看一下我的代码:

someMap.keySet().stream().filter(v -> !someList.contains(v)).forEach(someMap::remove);

我收到了java.util.ConcurrentModificationException。为什么?流不是并行的。最优雅的方法是什么?


问题答案:

@Eran已经解释了如何更好地解决此问题。我将解释为什么ConcurrentModificationException会发生。

ConcurrentModificationException发生这种情况是因为您正在修改流源。您Map可能是HashMapTreeMap或其他非并行地图。假设它是一个HashMap。每个流都有的支持Spliterator。如果分隔符没有IMMUTABLECONCURRENT特征,那么,如文档所述:

绑定后,ConcurrentModificationException如果发现结构上的干扰,分离器应尽力而为。执行此操作的拆分器称为 快速失败

因此,HashMap.keySet().spliterator()不是IMMUTABLE(因为Set可以修改)和不是CONCURRENT(并发更新对于而言是不安全的HashMap)。因此,它仅检测并发更改,ConcurrentModificationException并按分隔符文档的规定抛出该错误。

同样值得引用的HashMap文档:

由此类的所有“集合视图方法”返回的迭代器都是 快速失败的
:如果在创建迭代器后的任何时间对结构进行结构修改,则除了通过迭代器自己的remove方法之外,该迭代器都将抛出ConcurrentModificationException。因此,面对并发修改,迭代器会快速干净地失败,而不会在未来的不确定时间内冒任意,不确定的行为的风险。

请注意,迭代器的快速失败行为无法得到保证,因为通常来说,在存在不同步的并发修改的情况下,不可能做出任何严格的保证。快速失败的迭代器会ConcurrentModificationException尽力而为。因此,编写依赖于此异常的程序以确保其正确性是错误的:
迭代器的快速失败行为应仅用于检测错误

尽管它只涉及迭代器,但我相信拆分器也是如此。



 类似资料:
  • 我正在尝试对ResultSet进行更新,但遇到异常,。 它是PostgreSQL9.6.1.0,jdbc驱动程序版本postgresql-9.4.1212.jar从他们的网站下载(JDBC42 Postgreql驱动程序,版本9.4.1212从这里)。 结果如下。 这是虫子吗?我错过了一步吗?

  • 我正在使用python 3.4的curses,我需要一个简单的方法来用箭头键计数,每次我按上,x给自己加1,按下,它从自己减去1。

  • 我想在不断从客户端接收实时视频流的情况下使用MPEG-DASH技术。Web服务器获取实时视频流,不断生成m4s文件,并在mpd中声明它。因此可以不断播放新片段。(我使用的是FFMPEG的ffserver。因此视频流继续累积在 /tmp/feed1.ffm文件中。) 使用MP4Box似乎能够生成mpd,init。mp4,M4用于现有文件。但它似乎不支持直播。 我想要片段格式的MP4而不是mpeg-t

  • 当我试图获得悲观的旅行时间,以便在特定时间到达目的地时,我得到一个错误:{“error_message”:“请求无效。缺少'execution_time'参数。”,“路由”:[],“状态”:“无效的请求”}我的请求是:https://maps.googleapis.com/maps/api/directions/json?units=metric 当我使用departure_time而不是arri

  • 问题内容: 我有以下代码: 我不确定这是否正确,但是我在互联网上发现的信息残片使我认为它应该起作用。基本上,我想分块地流式传输文件,为此,我要从应用程序函数传回一个生成器。但是,这仅打印出标题,而实际上没有发送回任何数据,有人可以告诉我为什么吗? 或者,如果这是完全错误的,那么执行此操作的最佳方法是什么?我无法将整个文件缓冲在内存中,因为我将要使用的文件可能是千兆字节。 第三级问题:一旦完成输出,

  • 问题内容: 我有三节课。一种用于从网页中获取所有元素,一种用于对这些元素执行操作,另一种用于测试脚本。从测试脚本调用函数时,出现空指针异常。我发现这是因为我使用了@FindBy批注,但我不知道如何解决此问题。 元素类: 动作类: 测试脚本: 当我将WebDriver对象从测试脚本传递到元素类时,也不例外。由于没有WebDriver实例化,当我使用通过FindBy注释初始化的元素时,会发生问题。我该