优先级队列中的Java concurrentmodificationexception

时间:2017-01-31 13:17:50

标签: java iterator priority-queue concurrentmodification

我在迭代我的优先级队列时出现问题,导致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。 我可以知道如何解决这个问题吗?我在互联网上搜索,但仍无法找到解决方案。

3 个答案:

答案 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的默认实现)。