Java中递归使用Maps时出现ConcurrentModificationException异常

3
我们正在创建一个由JADE Agent结构中的AID组成的树形结构。 我们选择递归方式进行,以便代码可以在系统中有多少代理程序时执行,并且可以动态修改树形结构以适应当前系统中的代理程序数量。我不确定是否需要设置某种锁来确保在没有损坏结构完整性的情况下从Map对象中读取和写入数据。
这是引起问题的代码。
// BuildHierarchy method used to create the hierarchy based on Monitor Agents in the system
private void BuildHierarchy(Map<AID, Double>freqList, ArrayList<AID> childless, DefaultMutableTreeNode node){
    int i = 0;
    //creates an iterator for the freqList
    Iterator iter = freqList.entrySet().iterator();

    while(iter.hasNext()&& i < 2){

        Map.Entry pairs = (Map.Entry)iter.next();   
        //if (i<2){ 
            setParentNode((AID)pairs.getKey(), node);
        //}
        freqList.remove(pairs.getKey());
        i++;
    }
    BuildHierarchy(freqList, childless, node.getNextNode());
    BuildHierarchy(freqList, childless, node.getNextNode().getNextSibling());

}
2个回答

2

当您在迭代Set(或底层的Map)时,除了通过迭代器自身的remove操作或者抛出ConcurrentModificationException之外,您不能修改它。请尝试:

iter.remove();

替代

freqList.remove(pairs.getKey());

0
当在已实现的集合上创建迭代器时,它会在其上创建一个支持集,并有一个计数器来跟踪已实现的集合大小。在迭代过程中,如果修改了集合,例如 "freqList.remove(pairs.getKey());",则它将删除该元素并减小集合的大小。现在,当迭代器下一次调用next()操作时,它会感知到从计数器实例中修改了集合,并抛出ConcurrentModificationException异常。以下是HashIterator类的代码,可以让您清楚地了解它的工作原理。
     final Entry<K,V> nextEntry() {
      if (modCount != expectedModCount)
             throw new ConcurrentModificationException();
         Entry<K,V> e = next;
         if (e == null)
            throw new NoSuchElementException();

         if ((next = e.next) == null) {
            Entry[] t = table;
            while (index < t.length && (next = t[index++]) == null)
                 ;
         }
        current = e;
        return e;
     }

如果使用实际集合删除条目,则 modcount != expectedCount 将为真,并且会抛出异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接