我在迭代我的优先级队列时出现问题,导致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。 我可以知道如何解决这个问题吗?我在互联网上搜索,但仍无法找到解决方案。
答案 0 :(得分:1)
将您的代码更改为以下内容以解决问题 -
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()方法抛出,如果底层集合中有任何结构更改(在您的情况下为Queue),即添加或删除任何元素队列直接。它被称为Fail Fast Iterator
。
答案 1 :(得分:0)
尝试使用ConcurrentLinkedQueue而不是PriorityQueue
根据:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html
请注意,与大多数集合不同,size方法不是常量操作。由于这些队列的异步性质,确定当前元素数量需要遍历元素,因此如果在遍历期间修改此集合,则可能会报告不准确的结果。
答案 2 :(得分:0)
自Java8以来,您可以使用属于removeIf
合同的Collection
移除。
鉴于removeIf
方法采用谓词,您的代码可以简单如下:
priorityQueue.removeIf(patient -> patient.getName().equals(patientName));
对于你所遇到的并发异常,这只是因为你试图在迭代时直接删除调用PriorityQueue#remove
而导致迭代器过时。迭代时删除的正确方法是使用Iterator#next
然后使用Iterator#remove
(这实际上是removeIf
的默认实现)。