Java: SortedMap, TreeMap, vergleichbar? Wie benutzt man?
-
10-07-2019 - |
Frage
Ich habe eine Liste von Objekten I nach Eigenschaften eines ihrer Felder sortieren müssen. Ich habe gehört, dass SortedMap und Komparatoren sind der beste Weg, dies zu tun.
- ich implementieren Vergleichbar mit der Klasse ich Sortierung, oder muss ich eine neue Klasse erstellen?
- Wie kann ich die SortedMap instanziiert und in dem Vergleicher passieren?
- Wie funktioniert die Sortierung der Arbeit? Wird es automatisch alles sortieren als neue Objekte eingefügt werden?
EDIT: Dieser Code gibt mir eine Fehlermeldung:
private TreeMap<Ktr> collection = new TreeMap<Ktr>();
(Ktr implementiert Comparator<Ktr>
). Eclipse sagt es so etwas wie TreeMap<K, V>
erwartet, so dass die Anzahl der Parameter ich unrichtige.
Lösung
- Die einfachere Art und Weise ist
Comparable
mit Ihren vorhandenen Objekten zu implementieren, obwohl Sie stattdessen einComparator
schaffen könnte und auf denSortedMap
passieren.
Beachten Sie, dassComparable
undComparator
zwei verschiedene Dinge sind; eine Klasse UmsetzungComparable
vergleichtthis
auf ein anderes Objekt, während eine Klasse ImplementierungComparator
vergleicht zwei andere Objekte. - Wenn Sie
Comparable
implementieren, brauchen Sie nichts passieren besonderen in den Konstruktor. Rufen Sienew TreeMap<MyObject>()
. ( Edit:.! Abgesehen davon, dass natürlichMaps
müssen zwei generische Parameter, nicht ein Dummer me)
Wenn Sie stattdessen eine andere Klasse ImplementierungComparator
schaffen, eine Instanz dieser Klasse in den Konstruktor übergeben. - Ja, nach dem
TreeMap
Javadocs .
Edit: Auf Wiederlesen die Frage, nichts davon macht Sinn. Wenn Sie bereits eine Liste haben, ist das Vernünftigste, was zu tun Comparable
implementieren und rufen Sie dann Collections.sort
darauf. Keine Karten erforderlich sind.
Ein kleiner Code:
public class MyObject implements Comparable<MyObject> {
// ... your existing code here ...
@Override
public int compareTo(MyObject other) {
// do smart things here
}
}
// Elsewhere:
List<MyObject> list = ...;
Collections.sort(list);
Wie bei den SortedMap
, könnten Sie stattdessen ein Comparator<MyObject>
erstellen und übergeben es an Collections.sort(List, Comparator)
.
Andere Tipps
1.
Das hängt von der Situation ab. Sagen wir, das Objekt A vor dem Objekt B in Ihrem Set sortieren soll. Wenn es sinnvoll, im Allgemeinen macht eine weniger als B zu prüfen, dann Vergleichbare Umsetzung würde Sinn machen. Wenn der Auftrag Sinn macht nur in dem Kontext, in dem Sie den Satz verwenden, dann sollten Sie vielleicht einen Vergleicher erstellen.
2.
new TreeMap(new MyComparator());
oder ohne MyComparator Klasse zu erstellen:
new TreeMap(new Comparator<MyClass>() {
int compare(MyClass o1, MyClass o2) { ... }
});
3. Ja.
Da Sie eine Liste haben und eine Fehlermeldung erhalten, weil Sie ein Argument auf der Karte habe ich nehme an, Sie eine sortierte Menge wollen:
SortedSet<Ktr> set = new TreeSet<Ktr>(comparator);
Dies wird den Satz halten sortiert, das heißt einem Iterator werden die Elemente in ihrer Sortierreihenfolge zurück. Es gibt auch Methoden spezifisch für SortedSet die Sie könnten verwendet werden soll. Wenn Sie auch rückwärts gehen möchten, können Sie verwenden, NavigableSet .
Meine Antwort vorausgesetzt, dass Sie die TreeMap
Implementierung von SortedMap
verwenden.
1). Wenn TreeMap
verwenden, haben Sie die Wahl. Sie können entweder implementieren Comparable
direkt auf Ihrer Klasse oder eine separate Comparator
an den Konstruktor übergeben.
2). Beispiel:
Comparator<A> cmp = new MyComparator();
Map<A,B> map = new TreeMap<A,B>(myComparator);
3.) Ja, das ist richtig. Intern TreeMap verwendet einen rot-schwarzen Baum zu speichern Elemente, um wie sie eingesetzt werden; Die Zeit, Kosten eines Einsatzes (oder Wiedergewinnung) durchzuführen, ist O (log N).
Sie machen eine Comparator<ClassYouWantToSort>
. Dann wird der Vergleicher vergleicht das Feld, das Sie sortieren möchten.
Wenn Sie die TreeMap
erstellen, erstellen Sie eine TreeMap<ClassYouWantToSort>
, und Sie passieren in der Comparator
als Argument. Dann wird, wie Sie Objekte vom Typ ClassYouWantToSort
einzufügen, die TreeMap
verwendet Ihre Comparator
sie richtig zu sortieren.
EDIT: Wie Adamski bemerkt, können Sie auch ClassYouWantToSort
selbst Comparable
machen. Der Vorteil ist, dass man mit weniger Klassen zu tun hat, ist der Code einfacher und ClassYouWantToSort
bekommt eine günstige Standard-Bestellung. Der Nachteil ist, dass ClassYouWantToSort
keine einzige offensichtliche Ordnung haben, und so werden Sie haben Comparables
für andere Situationen sowieso implementieren. Sie können möglicherweise auch nicht ClassYouWantToSort
ändern.
EDIT2: Wenn Sie nur eine Reihe von Objekten, die Sie in die Sammlung sind zu werfen, und es ist kein Map
(dh von einem Satz von Objekten zum anderen kein Mapping ist) dann wollen Sie ein TreeSet
, kein TreeMap
.