Ich weiß, LinkedHashMaphat eine vorhersehbare Iterationsreihenfolge (Einfügereihenfolge). Wird diese Bestellung auch von der SetRücksendung LinkedHashMap.keySet()und der CollectionRücksendung LinkedHashMap.values()beibehalten?
Ich weiß, LinkedHashMaphat eine vorhersehbare Iterationsreihenfolge (Einfügereihenfolge). Wird diese Bestellung auch von der SetRücksendung LinkedHashMap.keySet()und der CollectionRü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
TreeMapKlasse, geben spezifische Garantien für ihre Reihenfolge. andere, wie dieHashMapKlasse, 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 Mapund LinkedHashMapgarantiert es.
Das ist schließlich der Punkt dieser Klasse.
Collectionist nur die Basisklasse für die Rückgabe von values (). Die Implementierung der zurückgegebenen Sammlung wird weiterhin von der gesteuert LinkedHashMap. In diesem LinkedHashMapFall wird eine LinkedValuesInstanz 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!
Setist eine Schnittstelle mit HashSet, TreeSetetc Wesen ihre Implementierungen. Die HashSetImplementierung der SetSchnittstelle garantiert keine Bestellung. AberTreeSet tut es. Auch LinkedHashSettut.
Daher hängt es davon ab, wie Setimplementiert wurde, um LinkedHashMapzu 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 SetdhKeySet . 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 LinkedHashMapund vergleichen Sie sie mit der, HashMapdie den Hauptunterschied zwischen HashMapund 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 Setund 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.
LinkedHashMapKlasse 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.