首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中使用addAll over Set时出现ConcurrentModification异常

在Java中使用addAll over Set时出现ConcurrentModification异常
EN

Stack Overflow用户
提问于 2010-10-12 13:07:37
回答 2查看 2.6K关注 0票数 0

我在Java应用程序中遇到了一个问题,这让我完全迷惑了。

当我尝试运行下面给出的代码时,Java在显示"if ( this.vertexStore.get (V ).addAll ( ConcurrentModificationException ) )“的行上抛出一个输出。

考虑到这是一个完全单线程的应用程序,我发现这非常奇怪,而且我实际上并没有修改我所能告诉的任何循环的东西?

事实上,我唯一能看到错误发生的地方是在addAll方法内部,但这也不应该发生,因为我正在使用Java类库中的HashMap和LinkedList……

代码语言:javascript
复制
private Queue<Vertex> worklist = new LinkedList<Vertex> ( );
protected Map<Vertex, Set<T>> vertexStore = new HashMap<Vertex, Set<T>> ( );

// . . .

while ( this.worklist.size ( ) > 0 ) {
        Vertex vertex = this.worklist.remove ( );

        Set<T> output = this.processVertice ( vertex, this.vertexStore.get ( vertex ) );

        this.vertexStore.put ( vertex, output );

        for ( Vertex v : vertex.edgesTo ( ) ) {
            // Conveniently, addAll returns true if the set changed
            if ( this.vertexStore.get ( v ).addAll ( output ) )
                this.worklist.add ( v );
        }
    }

编辑:错误跟踪:

代码语言:javascript
复制
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
    at DataFlowAnalyser.process(DataFlowAnalyser.java:41) (the if line)

任何好的想法都非常受欢迎!

PS:完整的源代码here (抱歉,缺少注释,代码未完成)

干杯,乔恩

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-12 14:55:06

您正在调用addAll并传递对Set本身的引用。如果调试代码,您将看到this.vertexStore.get(v)返回的对象与输出变量所引用的对象相同。

通常这对于HashSet来说不是问题,因为如果您只是添加所有相同的元素,addAll实际上不会修改HashSet的状态。然而,在本例中,您在将HamiltonPath实例添加到集合之后修改它们,这反过来会更改它们的散列代码,并使HashSet认为正在添加的对象与它已有的对象不同。

这里有一些代码比我的散文更好地说明了这个问题:

代码语言:javascript
复制
List<String> list1 = Arrays.asList("foo");
List<String> list2 = Arrays.asList("bar");
Set<List<String>> set = new HashSet<List<String>>();
set.add(list1);
set.add(list2);
list1.add("baz"); 
list2.add("qux");
set.addAll(set); // throws ConcurrentModificationException
票数 3
EN

Stack Overflow用户

发布于 2010-10-12 18:20:53

您的代码中断,因为您正在修改一个集合,而您正在对它进行迭代,而java不喜欢它。如果您想这样做,请使用使用与标准映射不同类型的迭代器的ConcurrentHashMap。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3911841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档