迭代排序树图:java.util.ConcurrentModificationException
iterating over sorted treemap: java.util.ConcurrentModificationException
我有 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、时间等)但不确定迭代器使用哪个参数。
这里是相关的代码部分(第二个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
class 的大厅代码:
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();
}
}
关于如何继续调试这个问题有什么建议吗?
已编辑: 这是一个常见的错误。当使用 Iterator
遍历集合时,您不能直接修改集合(添加或删除元素)。例如,删除必须通过 Iterator
本身完成。
正确的做法如下(不是一个完整的例子,只是为了说明问题):
Iterator<SimEvent> fit = future.iterator();
while (fit.hasNext()) {
SimEvent event = fit.next();
processEvent(event);
fit.remove();
}
当您遍历集合时,注意可能添加到集合或从集合中删除的其他线程。
我有 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、时间等)但不确定迭代器使用哪个参数。
这里是相关的代码部分(第二个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
class 的大厅代码:
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();
}
}
关于如何继续调试这个问题有什么建议吗?
已编辑: 这是一个常见的错误。当使用 Iterator
遍历集合时,您不能直接修改集合(添加或删除元素)。例如,删除必须通过 Iterator
本身完成。
正确的做法如下(不是一个完整的例子,只是为了说明问题):
Iterator<SimEvent> fit = future.iterator();
while (fit.hasNext()) {
SimEvent event = fit.next();
processEvent(event);
fit.remove();
}
当您遍历集合时,注意可能添加到集合或从集合中删除的其他线程。