So che LinkedHashMap
ha un ordine di iterazione prevedibile (ordine di inserimento). Anche il Set
reso LinkedHashMap.keySet()
e il Collection
reso LinkedHashMap.values()
mantengono questo ordine?
So che LinkedHashMap
ha un ordine di iterazione prevedibile (ordine di inserimento). Anche il Set
reso LinkedHashMap.keySet()
e il Collection
reso LinkedHashMap.values()
mantengono questo ordine?
Risposte:
L'interfaccia Mappa fornisce tre viste di raccolta , che consentono di visualizzare i contenuti di una mappa come un insieme di chiavi, raccolta di valori o insieme di mapping di valori-chiave. L' ordine di una mappa è definito come l'ordine in cui gli iteratori nelle viste di raccolta della mappa restituiscono i loro elementi. Alcune implementazioni di mappe, come la
TreeMap
classe, offrono garanzie specifiche sul loro ordine; altri, come laHashMap
classe, non lo fanno.
- Mappa
Questo elenco collegato definisce l'ordine di iterazione, che è normalmente l'ordine in cui le chiavi sono state inserite nella mappa ( ordine di inserimento ).
Quindi, sì, keySet()
, values()
, eentrySet()
(i tre punti di vista di raccolta di cui) i valori restituiti nell'ordine gli usi della lista collegate interne. E sì, JavaDoc per Map
e LinkedHashMap
garantirlo.
Questo è il punto di questa classe, dopo tutto.
Collection
è solo la classe base per quali valori restituiti (). L'implementazione della Collezione che restituisce è ancora controllata dal LinkedHashMap
. Nel LinkedHashMap
caso, sta restituendo LinkedValues
un'istanza, una classe privata all'interno di LinkedHashMap.java.
Map
) che lega esplicitamente l'ordine di una mappa agli iteratori nelle viste di raccolta della mappa (e chiarendo quali sono tali viste di raccolta). Quello era il pezzo mancante per me.
Guardando la fonte, sembra che lo sia. keySet()
, values()
e entrySet()
tutti usano lo stesso iteratore di voce internamente.
Non essere confuso con LinkedHashMap.keySet()
e LinkedHashMap.entrySet()
restituire Set e quindi non dovrebbe garantire l'ordinazione!
Set
è un'interfaccia con HashSet
, TreeSet
ecc. , le sue implementazioni. L' HashSet
implementazione Set
dell'interfaccia non garantisce l'ordinazione. Ma lo TreeSet
fa. AncheLinkedHashSet
fa .
Pertanto dipende da come Set
è stato implementato LinkedHashMap
per sapere se il riferimento Set restituito garantirà l'ordine o meno. Ho esaminato il codice sorgente di LinkedHashMap
, sembra così:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Pertanto LinkedHashMap / HashMap ha una propria implementazione di Set
ie KeySet
. Quindi non confonderlo conHashSet
.
Inoltre, l'ordine viene mantenuto dal modo in cui gli elementi vengono inseriti nel bucket. Guarda il addEntry(..)
metodo di LinkedHashMap
e confrontalo con quello di HashMap
cui evidenzia la differenza principale tra HashMap
e LinkedHashMap
.
Puoi presumere così. Javadoc dice "ordine di iterazione prevedibile" e gli unici iteratori disponibili in una mappa sono quelli per keySet (), entrySet () e valori ().
Quindi, in assenza di ulteriori qualifiche, si intende chiaramente applicare a tutti quegli iteratori.
AFAIK non è documentato, quindi non puoi "formalmente" assumerlo. È improbabile, tuttavia, che l'attuale attuazione cambierebbe.
Se si desidera garantire l'ordine, è possibile eseguire l'iterazione sulla mappa desiderata e inserirli in un set ordinato con una funzione di ordine di propria scelta, anche se si pagherà un costo di prestazione, naturalmente.
Guardando l'interfaccia restituisce una semplice Set
e non unaSortedSet
. Quindi non ci sono garanzie.
Prima di assumere una garanzia implicita osservando l'implementazione (sempre una cattiva idea), guarda anche le implementazioni in tutte le altre implementazioni Java :)
Ad esempio, è possibile creare un TreeSet con keySet nel costruttore.
Non penso che tu possa presumere l'ordinamento di keySet () e valori ().
Posso facilmente scrivere un'implementazione di LinkedHashMap che restituisce keySet () e valori () non ordinati, purché rimanga fedele al contratto di questi due metodi che sono definiti in Map e sovrascritti in HashMap.
LinkedHashMap
classe è mantenere l'ordinamento degli elementi durante l'iterazione della mappa e questo comportamento è ben specificato. Se scrivi una sottoclasse senza rispettare le specifiche della classe base, stai facendo qualcosa di molto sbagliato.
values()
ekeySet()
ho ampliato la domanda per includerlo. Ciò significa che più domande possono essere chiuse come duplicati di questo.