2017-01-31 4 views
1

Ich habe ein Problem beim Iterieren meiner Prioritätswarteschlange, die Concurrentmodificationexception kostet.Java concurrentmodificationexception in der Prioritätswarteschlange

Code für das Iterieren:

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); 
        } 


       } 

Es Fehler sagt, dass iter.next() ConcurrentModificationException kosten. Darf ich bitte wissen, wie man das löst? Ich habe das Internet gesucht, aber das kann immer noch keine Lösung finden.

+1

Sie können ein Element der Warteschlange, das Sie gerade durchlaufen, nicht löschen. – IQV

+0

Sie können keine Elemente aus dem Iterator entfernen –

+1

Verwenden Sie 'iter.remove();' zu entfernen, während iteracting –

Antwort

1

Code ändern zu folgenden für die Lösung von it -

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(); 
        } 


       } 

ErklärungConcurrentModificationException von next() -Methode von Iterator geworfen wird, wenn es in der zugrunde liegenden Auflistung (in Ihrem Fall jede strukturelle Veränderung Warteschlange), dh jedes Element wird direkt in der Warteschlange hinzugefügt oder entfernt. Es heißt Fail Fast Iterator.

+0

iter ... it ... :) –

+0

Danke @Vikas Sachdeva !! Es klappt! Kann ich warum wissen? Vielen Dank! – user7495150

+0

wollen Sie nicht erklären? Das Kopieren und Einfügen von Code mit Modifizieren wird nicht helfen zu lernen ... –

0

Try ConcurrentLinkedQueue statt Priorityqueue

zu verwenden Acording: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html

Beachten Sie, dass, anders als in den meisten Sammlungen ist die Größe Methode nicht ein konstanten Zeitbetrieb. Aufgrund der asynchronen Art dieser Warteschlangen erfordert das Bestimmen der aktuellen Anzahl von Elementen eine Durchquerung der Elemente und kann daher ungenaue Ergebnisse melden, wenn diese Sammlung während des Durchlaufs geändert wird.

+0

was ist das? Kannst du mehr erklären ? bevorzugt mit einem Beispiel zu sein –

0

Seit Java8 können Sie entfernen mit removeIf, die Teil von Collection Vertrag ist.

Da removeIf Verfahren ein Prädikat nimmt, könnte der Code so einfach sein wie:

priorityQueue.removeIf(patient -> patient.getName().equals(patientName)); 

Wie für die Concurrent Ausnahme, die Sie hatten, das einfach passiert, weil Sie PriorityQueue#remove direkt zu entfernen versucht Aufruf, während Sie bereits waren Iterieren, was den Iterator überflüssig machen würde. Der richtige Weg, um beim Iterieren zu entfernen, ist mit Iterator#next und dann Iterator#remove (das ist eigentlich, was die Standardimplementierung von removeIf tut).

Verwandte Themen