Java 优先级队列中的并发修改异常
Java concurrentmodificationexception in priority queue
我在迭代我的优先级队列时遇到问题,这会导致 Concurrentmodificationexception。
迭代代码:
Queue<Patient> pq = new PriorityQueue<Patient>();
Iterator<Patient> it = pq.iterator();
while(iter.hasNext()){
Patient current = iter.next();
if(current.getName().equals(patientName)){
pq.remove(p);
}
}
有错误说 iter.next() 消耗了 Concurrentmodificationexception。
我可以知道如何解决这个问题吗?我已经在互联网上搜索了,但仍然找不到解决方法。
尝试使用 ConcurrentLinkedQueue 而不是 PriorityQueue
根据:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html
Beware that, unlike in most collections, the size method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires a traversal of the elements, and so may report inaccurate results if this collection is modified during traversal.
将您的代码更改为以下以解决它 -
Queue<Patient> pq = new PriorityQueue<Patient>();
Iterator<Patient> iter = pq.iterator();
while(iter.hasNext()){
Patient current = iter.next();
if(current.getName().equals(patientName)){
iter.remove();
}
}
说明 ConcurrentModificationException
是从迭代器的 next() 方法抛出的,如果底层集合(在你的例子中是队列)即任何元素有任何结构变化直接在队列中添加或删除。它被称为Fail Fast Iterator
。
自 Java8 起,您可以删除使用 removeIf
,它是 Collection
合同的一部分。
鉴于 removeIf
方法采用谓词,您的代码可以像这样简单:
priorityQueue.removeIf(patient -> patient.getName().equals(patientName));
至于您遇到的并发异常,这只是因为您试图在已经迭代时直接删除 PriorityQueue#remove
调用,这会使迭代器过时。迭代时删除的正确方法是使用 Iterator#next
,然后使用 Iterator#remove
(这实际上是 removeIf
的默认实现)。
我在迭代我的优先级队列时遇到问题,这会导致 Concurrentmodificationexception。
迭代代码:
Queue<Patient> pq = new PriorityQueue<Patient>();
Iterator<Patient> it = pq.iterator();
while(iter.hasNext()){
Patient current = iter.next();
if(current.getName().equals(patientName)){
pq.remove(p);
}
}
有错误说 iter.next() 消耗了 Concurrentmodificationexception。 我可以知道如何解决这个问题吗?我已经在互联网上搜索了,但仍然找不到解决方法。
尝试使用 ConcurrentLinkedQueue 而不是 PriorityQueue
根据:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html
Beware that, unlike in most collections, the size method is NOT a constant-time operation. Because of the asynchronous nature of these queues, determining the current number of elements requires a traversal of the elements, and so may report inaccurate results if this collection is modified during traversal.
将您的代码更改为以下以解决它 -
Queue<Patient> pq = new PriorityQueue<Patient>();
Iterator<Patient> iter = pq.iterator();
while(iter.hasNext()){
Patient current = iter.next();
if(current.getName().equals(patientName)){
iter.remove();
}
}
说明 ConcurrentModificationException
是从迭代器的 next() 方法抛出的,如果底层集合(在你的例子中是队列)即任何元素有任何结构变化直接在队列中添加或删除。它被称为Fail Fast Iterator
。
自 Java8 起,您可以删除使用 removeIf
,它是 Collection
合同的一部分。
鉴于 removeIf
方法采用谓词,您的代码可以像这样简单:
priorityQueue.removeIf(patient -> patient.getName().equals(patientName));
至于您遇到的并发异常,这只是因为您试图在已经迭代时直接删除 PriorityQueue#remove
调用,这会使迭代器过时。迭代时删除的正确方法是使用 Iterator#next
,然后使用 Iterator#remove
(这实际上是 removeIf
的默认实现)。