Warum funktioniert Collections.sort (List) in Java 8 mit CopyOnWriteArrayList, aber nicht in Java 7?

8

Ich kann mit dem folgenden Code und Java 8 eine Liste von Benutzern ohne Probleme sortieren:

%Vor%

Nun bin ich zu Java 7 gewechselt und habe bei Eclipse keine Fehler gesehen. Aber jetzt, wenn ich unter Java 7 lief, habe ich diesen Fehler:

%Vor%

Wie man es repariert?

    
Tum 16.01.2016, 13:06
quelle

3 Antworten

12

Es gab einen Wechsel zwischen Java 7 (und früher Version von Java 8) und Java 8u20 in der Art Collections.sort work ( Ausgabe 8032636 , wie von Holger vermerkt.

Java 7 Collections.sort(list, c) gibt Folgendes an:

  

Diese Implementierung lädt die angegebene Liste in ein Array, sortiert das Array und iteriert über die Liste, wobei jedes Element an der entsprechenden Position im Array zurückgesetzt wird. Dies vermeidet die n² log (n) -Leistung, die sich aus dem Versuch ergibt, eine verknüpfte Liste an Ort und Stelle zu sortieren.

Betrachten Sie den Code , indem Sie eine ListIterator von der Liste erhalten. % Co_de% CopyOnWriteArrayList Methode gibt an, dass der zurückgegebene Iterator die Operation listIterator() nicht unterstützt:

  

Der zurückgegebene Iterator bietet eine Momentaufnahme des Status der Liste, als der Iterator erstellt wurde. Beim Durchlaufen des Iterators ist keine Synchronisation erforderlich. Der Iterator unterstützt die Methoden set , remove oder set NICHT .

Dies erklärt den Fehler, den Sie bei der Ausführung Ihres Codes mit Java 7 bekommen. Als Workaround können Sie auf diese Frage , wo die Antwort ist, den Inhalt der Liste in ein Array abzulegen, das Array zu sortieren und die Elemente wieder in die Liste aufzunehmen.

In Java 8 add geänderte Implementierung:

  

Diese Implementierung wird mithilfe der angegebenen Liste und des Komparators in die Methode Collections.sort(list, c) verschoben.

Und die neue Methode List.sort(Comparator) (eingeführt in Java 8) verwendet den Listen-Iterator nicht, damit er korrekt funktioniert.

    
Tunaki 16.01.2016, 13:25
quelle
2

Collections.sort() verwendet in Java 7 (und früheren Versionen von Java 8) die set() des Listen-Iterators, um die Liste zu ändern. Aber der Iterator von CopyOnWriteArrayList ist explizit dokumentiert, da er diese Operation nicht unterstützt.

Wie man es repariert? Verwandle deine CopyOnWriteArrayList in eine reguläre ArrayList oder ein Array, sortiere das und lösche dann die CopyOnWriteArrayList und fülle sie erneut mit der sortierten Liste.

Ich empfehle dringend, Ihren Komparator viel einfacher zu machen, indem Sie Integer.compare() und Boolean.compare() verwenden.

    
JB Nizet 16.01.2016 13:14
quelle
1

In Java 8 wurde die Implementierung von Collections.sort(List, Comparator) so geändert, dass sie nun in eine neue Methode sort in der Schnittstelle List . Die Standardimplementierung dieser sort -Methode scheint das vorherige Verhalten zu sein (dh mit List.listIterator() , was immer noch mit UnsupportedOperationException fehlschlagen würde), aber die CopyOnWriteArrayList stellt explizit eine andere Version zur Verfügung, die kein% co_de verwendet %:

%Vor%     
Marvin 16.01.2016 13:31
quelle

Tags und Links