Ich weiß, LinkedHashMap
hat eine vorhersehbare Iterationsreihenfolge (Einfügereihenfolge). Wird diese Bestellung auch von der Set
Rücksendung LinkedHashMap.keySet()
und der Collection
Rücksendung LinkedHashMap.values()
beibehalten?
Ich weiß, LinkedHashMap
hat eine vorhersehbare Iterationsreihenfolge (Einfügereihenfolge). Wird diese Bestellung auch von der Set
Rücksendung LinkedHashMap.keySet()
und der Collection
Rücksendung LinkedHashMap.values()
beibehalten?
Antworten:
Die Kartenschnittstelle bietet drei Sammlungsansichten , mit denen der Inhalt einer Karte als eine Reihe von Schlüsseln, eine Sammlung von Werten oder eine Reihe von Schlüsselwertzuordnungen angezeigt werden kann. Die Reihenfolge einer Karte ist definiert als die Reihenfolge, in der die Iteratoren in den Sammlungsansichten der Karte ihre Elemente zurückgeben. Einige Kartenimplementierungen, wie die
TreeMap
Klasse, geben spezifische Garantien für ihre Reihenfolge. andere, wie dieHashMap
Klasse, tun das nicht.
- Karte
Diese verknüpfte Liste definiert die Iterationsreihenfolge, die normalerweise die Reihenfolge ist, in der Schlüssel in die Karte eingefügt wurden ( Einfügereihenfolge ).
Also, ja, keySet()
, values()
, und entrySet()
(die drei Sammel Ansichten erwähnt) Rückgabewerte in der Reihenfolge der internen verknüpften Liste Anwendungen. Und ja, das JavaDoc dafür Map
und LinkedHashMap
garantiert es.
Das ist schließlich der Punkt dieser Klasse.
Collection
ist nur die Basisklasse für die Rückgabe von values (). Die Implementierung der zurückgegebenen Sammlung wird weiterhin von der gesteuert LinkedHashMap
. In diesem LinkedHashMap
Fall wird eine LinkedValues
Instanz zurückgegeben, eine private Klasse in LinkedHashMap.java.
Map
) verlinken, die die Reihenfolge einer Karte explizit mit den Iteratoren in den Sammlungsansichten der Karte verknüpft (und klar macht, um welche Sammlungsansichten es sich handelt). Das war das fehlende Stück für mich.
Wenn man sich die Quelle ansieht, sieht es so aus. keySet()
, values()
Und entrySet()
alle verwenden die gleichen Eintrag Iterator intern.
Verwechsle dich nicht mit LinkedHashMap.keySet()
und LinkedHashMap.entrySet()
Rückkehr Set und daher sollte es keine Garantie für Ihre Bestellung!
Set
ist eine Schnittstelle mit HashSet
, TreeSet
etc Wesen ihre Implementierungen. Die HashSet
Implementierung der Set
Schnittstelle garantiert keine Bestellung. AberTreeSet
tut es. Auch LinkedHashSet
tut.
Daher hängt es davon ab, wie Set
implementiert wurde, um LinkedHashMap
zu wissen, ob die zurückgegebene Set-Referenz die Bestellung garantiert oder nicht. Ich habe den Quellcode von durchgesehen LinkedHashMap
, es sieht so aus:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Somit hat LinkedHashMap / HashMap eine eigene Implementierung von Set
dhKeySet
. Verwechseln Sie dies also nicht mit HashSet
.
Die Reihenfolge wird auch dadurch beibehalten, wie die Elemente in den Bucket eingefügt werden. Schauen Sie sich die addEntry(..)
Methode von an LinkedHashMap
und vergleichen Sie sie mit der, HashMap
die den Hauptunterschied zwischen HashMap
und hervorhebt LinkedHashMap
.
Das können Sie davon ausgehen. Der Javadoc sagt "vorhersehbare Iterationsreihenfolge", und die einzigen in einer Karte verfügbaren Iteratoren sind die für keySet (), entrySet () und values ().
In Ermangelung einer weiteren Qualifikation ist es eindeutig beabsichtigt, auf alle diese Iteratoren anzuwenden.
AFAIK ist nicht dokumentiert, so dass Sie dies nicht "formal" annehmen können. Es ist jedoch unwahrscheinlich, dass sich die derzeitige Implementierung ändert.
Wenn Sie die Reihenfolge sicherstellen möchten, können Sie die Karteneinträge durchlaufen und sie in ein sortiertes Set mit einer Bestellfunktion Ihrer Wahl einfügen, obwohl Sie natürlich die Leistungskosten bezahlen.
Wenn Sie sich die Benutzeroberfläche ansehen, wird eine Ebene Set
und keine zurückgegeben SortedSet
. Es gibt also keine Garantien.
Bevor Sie eine implizite Garantie übernehmen, indem Sie sich die Implementierung ansehen (immer eine schlechte Idee), schauen Sie sich auch die Implementierungen in allen anderen Java-Implementierungen an :)
Sie können beispielsweise ein TreeSet mit dem keySet im Konstruktor erstellen.
Ich glaube nicht, dass Sie die Reihenfolge von keySet () und values () annehmen können.
Ich kann leicht eine Implementierung von LinkedHashMap schreiben, die Ihnen ungeordnetes keySet () und values () zurückgibt, solange ich mich an den Vertrag dieser beiden Methoden halte, die in Map definiert und in HashMap überschrieben werden.
LinkedHashMap
Klasse besteht darin, die Reihenfolge der Elemente während der Iteration der Karte beizubehalten, und dieses Verhalten ist genau spezifiziert. Wenn Sie eine Unterklasse schreiben, ohne die Basisklassenspezifikation einzuhalten, machen Sie etwas sehr Falsches.
values()
sowie ansprechenkeySet()
, habe ich die Frage um das erweitert. Dies bedeutet, dass weitere Fragen als Duplikate davon geschlossen werden können.