相关疑难解决方法(0)

迭代集合,在循环中删除对象时避免使用ConcurrentModificationException

我们都知道你不能这样做:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

ConcurrentModificationException等等......这显然有时起作用,但并非总是如此.这是一些特定的代码:

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<>();

    for (int i = 0; i < 10; ++i) {
        l.add(4);
        l.add(5);
        l.add(6);
    }

    for (int i : l) {
        if (i == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}
Run Code Online (Sandbox Code Playgroud)

当然,这会导致:

Exception in thread "main" java.util.ConcurrentModificationException
Run Code Online (Sandbox Code Playgroud)

...即使多线程没有这样做......无论如何.

什么是这个问题的最佳解决方案?如何在循环中从集合中删除项而不抛出此异常?

我也在Collection这里使用任意,不一定是ArrayList,所以你不能依赖get.

java iteration collections

1158
推荐指数
12
解决办法
46万
查看次数

ConcurrentModificationException和HashMap

我正在使用JPA持久化对象.Main对象与另一个对象具有一个拥有的One-Many关系.另一个对象存储在HashMap中.什么样的同步可以解决这个问题?它似乎发生在完全随机的时间,并且非常难以预测.这是我得到的例外:

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$ValueIterator.next(Unknown Source)
        at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
Run Code Online (Sandbox Code Playgroud)

java collections exception concurrentmodification

118
推荐指数
4
解决办法
14万
查看次数

在迭代它时从java中的集合中删除项目

我希望能够在迭代它时从一个集合中删除多个元素.最初我希望迭代器足够智能,以便下面的天真解决方案能够工作.

Set<SomeClass> set = new HashSet<SomeClass>();
fillSet(set);
Iterator<SomeClass> it = set.iterator();
while (it.hasNext()) {
    set.removeAll(setOfElementsToRemove(it.next()));
}
Run Code Online (Sandbox Code Playgroud)

但这引发了一场ConcurrentModificationException.

请注意,iterator.remove()将无法正常工作,因为我需要一次删除多个东西.还假设无法识别"动态"删除哪些元素,但可以编写该方法setOfElementsToRemove().在我的特定情况下,它将占用大量内存和处理时间来确定迭代时要删除的内容.由于内存限制,也无法进行复制.

setOfElementsToRemove()将生成一些我想删除的SomeClass实例集,fillSet(set)并将用条目填充集合.

在搜索Stack Overflow之后,我找不到一个很好的解决方案来解决这个问题,但是几个小时后我才意识到以下情况可以解决这个问题.

Set<SomeClass> set = new HashSet<SomeClass>();
Set<SomeClass> outputSet = new HashSet<SomeClass>();
fillSet(set);
while (!set.isEmpty()) {
    Iterator<SomeClass> it = set.iterator();
    SomeClass instance = it.next();
    outputSet.add(instance);
    set.removeAll(setOfElementsToRemoveIncludingThePassedValue(instance));
}
Run Code Online (Sandbox Code Playgroud)

setOfElementsToRemoveIncludingThePassedValue()将生成一组要删除的元素,包括传递给它的值.我们需要删除传递的值,因此set将为空.

我的问题是,是否有人有更好的方法这样做,或者是否有支持这种删除的收集操作.

此外,我认为我会发布我的解决方案,因为似乎有需要,我想贡献Stack Overflow的优秀资源.

java collections set

30
推荐指数
4
解决办法
6万
查看次数