迭代已排序的树形图:java.util.ConcurrentModificationException

时间:2017-06-07 10:22:31

标签: java iterator treemap sortedset

我掌握Java的基础知识,目前正在使用基于Java的代码。

编辑:我没有写代码

我正在迭代Event对象的有序树形图,并在我尝试获取下一个元素时获取此异常:

java.util.ConcurrentModificationException at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) at java.util.TreeMap$KeyIterator.next(Unknown Source)

我认为这应该是由于迭代器比较器合并的具有相同值的多个条目的存在(请参阅此question,但我不知道如何找到使用的密钥对象。对象Event有许多参数(如id,time等),但不确定哪一个用于迭代器。

以下是相关代码部分(第二个SimEvent first = fit.next();中的例外):

    if (future.size() > 0) {
        List<SimEvent> toRemove = new ArrayList<SimEvent>();
        Iterator<SimEvent> fit = future.iterator();
        queue_empty = false;
        SimEvent first = fit.next();
        processEvent(first);
        future.remove(first);

        fit = future.iterator();

        // Check if next events are at same time...
        boolean trymore = fit.hasNext();
        while (trymore) {
            SimEvent next = fit.next();
            if (next.eventTime() == first.eventTime()) {
                processEvent(next);
                toRemove.add(next);
                trymore = fit.hasNext();
            } else {
                trymore = false;
            }
        }

        future.removeAll(toRemove);

    } else {...}

编辑:future班级的大厅代码:

public class FutureQueue {

    /** The sorted set. */
    private final SortedSet<SimEvent> sortedSet = new TreeSet<SimEvent>();

    /** The serial. */
    private long serial = 0;

    /**
     * Add a new event to the queue. Adding a new event to the queue preserves the temporal order of
     * the events in the queue.
         * 
     * @param newEvent The event to be put in the queue.
     */
    public void addEvent(SimEvent newEvent) {
        newEvent.setSerial(serial++);
        sortedSet.add(newEvent);
    }

    /**
    * Add a new event to the head of the queue.
    * 
    * @param newEvent The event to be put in the queue.
    */
    public void addEventFirst(SimEvent newEvent) {
        newEvent.setSerial(0);
        sortedSet.add(newEvent);
    }

    /**
     * Returns an iterator to the queue.
     * 
     * @return the iterator
     */
     public Iterator<SimEvent> iterator() {
        return sortedSet.iterator();
     }

    /**
     * Returns the size of this event queue.
     * 
     * @return the size
     */
    public int size() {
        return sortedSet.size();
    }

    /**
     * Removes the event from the queue.
     * 
     * @param event the event
     * @return true, if successful
     */
    public boolean remove(SimEvent event) {
        return sortedSet.remove(event);
    }

    /**
     * Removes all the events from the queue.
     * 
     * @param events the events
     * @return true, if successful
     */
    public boolean removeAll(Collection<SimEvent> events) {
        return sortedSet.removeAll(events);
    }


    public void clear() {
        sortedSet.clear();
    }
}

有关如何继续调试此问题的任何建议吗?

1 个答案:

答案 0 :(得分:0)

已编辑:这是一个常见的错误。使用Iterator迭代集合时,无法直接修改集合(添加或删除元素)。例如,删除必须通过Iterator本身完成。

正确的方法如下(不是一个完整的例子,只是为了说明这一点):

Iterator<SimEvent> fit = future.iterator();
while (fit.hasNext()) {
    SimEvent event = fit.next();
    processEvent(event);
    fit.remove();
}

在迭代它时,请注意可能在集合中添加或删除的其他线程。