java - 集和 ConcurrentModificationException

标签 java loops foreach set

我有一个带有 Set 类型的 for every 循环。

当我循环遍历这个集合时,我向其中添加元素。

 for (Object o: Set) {
    //i do something and add to the set
  }

我不断收到ConcurrentModificationException 。但我不知道如何添加到此 Set那不会导致这个异常。我无法为每个不起作用的循环创建一个新的循环。

有人能指出我正确的方向吗?

最佳答案

你需要要么

  • 使用不会触发 ConcurrentModifcationException 的 Set,例如ConcurrentXxxSet
  • 在更改之前先复制该集合。

最简单的改变是

for (Object o: set.toArray()) {
    if (condition(o))
       set.add(something);
}

使用泛型,一个更简单的解决方案可能是

Set<T> set = 
for(T t: new HashSet<T>(set)) {
   // something which might add to set
}

注意:这将防止它迭代您刚刚添加的元素。 注意2:使用并发集可能会导致您看到添加的元素,也可能看不到。

如果您确实需要在添加元素时查看它们,则需要使用列表,可能会替代,或者同时使用。

List<T> list = new ArrayList<>(set);

for(int i = 0; i < list.size(); i++) {
    T t = list.get(i);

    if (condition)
        // if it is not a duplicate
        if (set.add(something))
            list.add(something);
}

这将使您能够以可靠的方式查看已在循环中添加的元素。注意:需要注意不要创建无限循环并耗尽内存。

另一种方法是使用队列而不是列表。这可能会更好,但我怀疑效率较低。

Queue<T> q = new ConcurrentLinkedQueue<>(set);

for(T t : q) {
    if (condition)
        // if it is not a duplicate
        if (set.add(something))
            q.add(something);
}

关于java - 集和 ConcurrentModificationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24695468/

相关文章:

java - 定义 Spring 组件时出错

java - Android: fragment 未附加到 Activity 错误

SwiftUI 文本在 ForEach 内部时不会本地化

javascript - jQuery 中的 for-each 循环等效于什么?

linux - Makefile 中的 foreach 不显示文件列表

java - 我应该使用 AOP 来解决这个横切关注点吗?

java - 如何使用kafka流加入主题

java - 在循环中添加输出/字符串

c - 为什么我的 C 代码不打印任何输出?

javascript - Google Maps API 仅显示一个信息窗口 - 循环问题