Ich denke, dass alle oben genannten Punkte diese Frage aus folgenden Gründen nicht beantworten,
- Da dieselbe Funktionalität auch durch die Verwendung anderer Sammlungen wie TreeSet, Collections, PriorityQueue usw. erreicht werden kann ( aber dies ist eine Alternative, die auch ihre Beschränkungen auferlegt, d.h. Set entfernt doppelte Elemente. Einfach zu sagen, auch wenn es keine Einschränkung auferlegt, ist keine Antwort auf die Frage, warum SortedList nicht von der Java-Gemeinschaft erstellt wurde )
- Da Listenelemente keine compare/equals-Methoden implementieren ( Dies gilt für Set & Map auch, wo im Allgemeinen Elemente nicht implementieren Comparable-Schnittstelle, aber wenn wir diese Elemente benötigen, um in sortierter Reihenfolge zu sein und wollen TreeSet/TreeMap verwenden, sollten Elemente implementieren Comparable-Schnittstelle )
- Da List die Indizierung verwendet & aufgrund der Sortierung wird es nicht funktionieren ( Dies lässt sich durch die Einführung einer Zwischenschnittstelle/abstrakten Klasse leicht bewerkstelligen )
aber keine hat den genauen Grund dahinter gesagt & wie ich glaube, diese Art von Fragen können am besten von Java-Community selbst beantwortet werden, da es nur eine & spezifische Antwort haben, aber lassen Sie mich mein Bestes versuchen, diese als folgende zu beantworten,
Wie wir wissen, ist das Sortieren eine teure Operation, und es gibt einen grundlegenden Unterschied zwischen Liste und Set/Map, nämlich dass es in der Liste Duplikate geben kann, in Set/Map aber nicht. Dies ist der Hauptgrund, warum wir eine Standardimplementierung für Set/Map in Form von TreeSet/TreeMap haben. Intern ist dies ein Red Black Tree mit jeder Operation (Einfügen/Löschen/Suchen), die die Komplexität von O(log N) wo die Liste aufgrund von Duplikaten nicht in diese Datenspeicherstruktur passen könnte.
Nun stellt sich die Frage, ob wir auch eine Standardsortiermethode für die Liste wählen können, wie MergeSort die verwendet wird von Collections.sort(list)
Methode mit der Komplexität von O(N log N) . Die Gemeinschaft hat dies nicht absichtlich getan, da wir mehrere Möglichkeiten für Sortieralgorithmen für nicht eindeutige Elemente haben wie QuickSort, ShellSort, RadixSort ...usw. In Zukunft kann es noch mehr geben. Außerdem funktioniert ein und derselbe Sortieralgorithmus je nach den zu sortierenden Daten manchmal unterschiedlich. Deshalb wollte man sich diese Option offen halten und uns die Wahl überlassen. Dies war bei Set/Map nicht der Fall, da O(log N) ist die beste Sortierkomplexität.
3 Stimmen
Hat stackoverflow.com/questions/416266/sorted-collection-in-java Ihnen helfen?
9 Stimmen
Welches Ergebnis erwarten Sie also, wenn Sie ein Element in der Mitte der Liste einfügen?
6 Stimmen
@bestsss Es wäre durchaus möglich, eine SortedList-Klasse zu haben, die nicht die java.util.List-Schnittstelle implementiert. Lesen Sie die Frage als eine Anfrage, warum es keine Datenstruktur gibt, die die gewünschte Funktionalität unterstützt. Lassen Sie sich nicht von unbedeutenden Details wie der Namensgebung ablenken.
0 Stimmen
@Alderath, die übliche Struktur dafür ist ein Baum (rot/schwarz, avl oder btree) mit zusätzlichen prev/next-Links zur Unterstützung der Ordnung. Ich verwende eine ähnliche Struktur rot/schwarz mit vorhergehenden/nächsten Links. Das ist allerdings eine ziemliche Nischenanwendung. Der Baum kann sowohl in geordneter als auch in eingefügter Reihenfolge durchlaufen werden, hat O(logn) find/contains aber get(int) ist O(n). Angesichts der Tatsache, dass es sich um eine Nischenanwendung handelt, würde ich annehmen, dass es den Entwicklern überlassen wurde, eine solche zu implementieren, wenn sie es brauchen.
6 Stimmen
Nicht die Beantwortung der Frage nach dem "Warum", sondern die einfachste Abhilfe für TreeSet ist es, einen Comparator zu verwenden, der niemals Null zurückgibt, z. B.
int diff = this.score - that.score;
return (diff == 0) ? 1 : diff;
Da es sich um einen stinkenden Hack handelt, würde ich dies als anonymes Konstruktorargument bereitstellen, anstatt Comparable zu implementieren.0 Stimmen
@earcam Wie soll man in so einem Set überhaupt etwas finden?
set.add(X); Y = set.get(X);
wird mit Sicherheit null zurückgeben.0 Stimmen
@user13784117, ich glaube, Sie haben das falsch verstanden und BTW
Set
implementiert nichtget
- Notiz; ich würde sagen, es ist ein Stinkmorchel - Der Punkt, auf den ich hinauswollte, ist, dass mein Vorschlag mehrere identische Werte in einerSet
und tut dies amadd
Vermeidung von Kosten fürCollections.sort(List)
. Dieser stinkende Hack versagt bei einer Reihe von Szenarien, wie zum Beispielcontains
- nicht für die Verwendung, sondern für die Konvertierung gedacht war; ich vermute stark, dass es schneller ist (in Bezug auf die Zeitkomplexität für riesig Sammlungen) zu verwenden und dann in eine Liste mit z.B. zu dumpen.ArrayList
Konstrukteur oderaddAll
(unwahrscheinlich, dass es besser für Big-O-Speicher ist)0 Stimmen
Mein Fehler bei
get
- aber ähnliche Argumente fürcontains
. Außerdem verstößt Ihr Komparator sicherlich gegen einen Vertrag, da compare(a,b) == 1 und compare(b,a) == 1, d.h. a > b und b > a. Ich würde zumindest für Konsistenz im Fall von a.equals(b) durch die Bestellung auf etwas anderes, vielleicht Vergleichen von System.identityHashCode-Werte.0 Stimmen
Ich habe diesen interessanten Hack ausprobiert, aber er hat auch den Nachteil, dass set.removeAll(set2) nichts entfernt, weil die removeAll-Methode irgendwie den Comparator verwendet.