- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
通常,当迭代正在进行时进行修改时,会立即引发 ConcurrentModificationException。
但是,使用流 API 的 forEachOrdered 方法,每次修改后都不会抛出异常。相反,在迭代过程中可以成功修改,并最终在整个操作完成后抛出异常。有人可以向我解释这是怎么发生的吗?
下面的代码生成 3 个范围从 -0.5 到 0.5 的随机数。然后过滤掉负值。
HashMap<Integer, Double> positiveNegative = new HashMap<>();
for (int i = 0; i < 3; i++) {
double value =Math.random() - 0.5;
positiveNegative.put(i, value);
}
System.out.println(positiveNegative);
//filter out the negative value
positiveNegative.entrySet().stream()
.filter((entry) -> (entry.getValue() < 0))
.forEachOrdered(entry -> {
System.out.println(entry);
positiveNegative.remove(entry.getKey());
System.out.println(positiveNegative);
});
System.out.println(positiveNegative);
{0=-0.38785299800912576, 1=-0.11085161629013052, 2=-0.3516129030809366}
0=-0.38785299800912576
{1=-0.11085161629013052, 2=-0.3516129030809366}
1=-0.11085161629013052
{2=-0.3516129030809366}
2=-0.3516129030809366
{}
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1751)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEachOrdered(ReferencePipeline.java:502)
at Solution.main(Solution.java:51)
最佳答案
Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw
ConcurrentModificationException
on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.
您的示例中不涉及并发,但要点仍然存在;此功能仅用于检测错误,而不是保证是否或何时引发异常。要检测错误,只要抛出异常就足够了,即使仅在迭代结束时也是如此。
对于 Iterator
的 hasNext()
和 next()
方法,无法控制调用者。调用者不需要迭代到集合的末尾,换句话说,在迭代器被放弃之前,每个方法调用都可能是最后一个方法调用。所以这些方法都不能推迟检查。
相比之下,Iterator
和 Spliterator
的 forEachRemaining
方法控制迭代循环并知道它们何时退出,因此,可以省略每次迭代中的检查并在最后执行一次检查,假设我们有一个专门的实现,而不是默认方法,它别无选择,只能重复调用单元素迭代方法。
正如您在堆栈跟踪中看到的,forEachOrdered
Stream 操作最终在 HashMap$EntrySpliterator.forEachRemaining
处结束,这是一个利用该机会的专门实现。显而易见的原因是性能,因为您不想浪费 CPU 周期来测试每次迭代中的条件,无论如何,当合约允许在最后执行一次时(如果我们从尽最大努力基础契约(Contract)中推断出一项要求)。
关于lambda - 为什么在不安全操作之后而不是在整个 forEach 循环之后抛出 ConcurrentModificationException ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57985323/
这个问题在这里已经有了答案: Why is a ConcurrentModificationException thrown and how to debug it (8 个答案) 关闭 3 年前。
这个问题已经有答案了: Concurrent Modification exception [duplicate] (9 个回答) 已关闭 8 年前。 在oldSet.removeAll(已删除);抛
这个问题在这里已经有了答案: Concurrent Modification exception [duplicate] (9 个回答) 关闭 9 年前。 我的程序抛出 ConcurrentModi
我有以下结构: public class Object1{ private HashMap myMap; ... public void cancelItem(Item o)
在本例中使用 list.remove((Object)93) 会导致 ConcurrentModificationException: List list = new ArrayList<>(); l
更新应用程序后,我收到来自 Firebase 的错误几乎在所有 Activity 中。 Fatal Exception: java.lang.RuntimeException: Unable to s
我有大量的东西,一个重复迭代它们的线程,以及一个偶尔删除或添加单个东西的单独线程。事物在同步链表中: private List things = Collections.synchronizedLis
在 DTO 中我有 public class ProductTypesDto extends BaseDto { private List colors = new ArrayList<>();
我正在创建一个 Swing 应用程序来制作游戏。它在屏幕外的随机位置创建图像,当它们离开屏幕时我想将它们删除。请看一下代码片段: public void checkTrolls(){ //CAUSES
我在向 Android 表插入数据时遇到问题。这是我的 Dao 函数: @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(frei
我有一个 Grails (2.4.3) 应用程序,它使用 PersistenceListener 来监听 GORM 事件。 PersistenceListener 工作正常。在 PreUpdate 事
基于 Spring Boot、spring-data-jpa 的大型 REST Web 应用程序。我有 PersonEntity ,它与 ParentEntity 具有 ManyToOne 关系。关系
我有一个作业要编写一个 Java 程序,该程序将读取上下文无关语法并返回所有非终结符的 FirstSet。我使用 FirstSet() 方法采用了递归方法: public static ArrayLi
我收到java.util.ConcurrentModificationException,但我不知道为什么。 在 Logcat 中,它指向此代码,但我没有看到任何可能导致 ConcurrentModi
我在以下情况下收到 ConcurrentModificationException 错误。线路发生这种情况的地方标有“ list = Collections.synchronizedList(them
自过去两个小时以来,我一直在尝试解决此异常..我得到了抛出异常的代码行..但没有找到解决方案..请帮助我发生错误@ mUsers.add(user);//在其他部分 private void read
我有以下代码: List list = getItems(); //where getItems() returns List do { list.add(ad
我得到ConcurrentModificationException当迭代 map 的内容时 for (String sourceKey : sMap.getContent().keySet(
代码是葡萄牙语的,对此我很抱歉。 我在这里读到另一个问题,因为我正在使用progSelecionada.remove(),所以抛出了异常,所以我更改为iterator.remove()但错误仍然存
我目前正在用 Java 编写多人游戏。我当前的代码(即出现错误)是这样的。 @Override public void onClose(WebSocket conn, int code, String
我是一名优秀的程序员,十分优秀!