L'ordine è garantito per la restituzione di chiavi e valori da un oggetto LinkedHashMap?


162

So che LinkedHashMapha un ordine di iterazione prevedibile (ordine di inserimento). Anche il Setreso LinkedHashMap.keySet()e il Collectionreso LinkedHashMap.values()mantengono questo ordine?


1
Dal momento che tutte le risposte affrontano il problema values()e keySet()ho ampliato la domanda per includerlo. Ciò significa che più domande possono essere chiuse come duplicati di questo.
Duncan Jones,

Risposte:


226

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 la HashMapclasse, 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 ).

- LinkedHashMap

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 Mape LinkedHashMapgarantirlo.

Questo è il punto di questa classe, dopo tutto.


8
anche l'iterazione sulla mappa viene eseguita più velocemente utilizzando una LinkedHashMap rispetto a una HashMap.
Thierry,

2
valori () restituisce una raccolta. non un elenco. come lo tiene in ordine?
Dejell,

7
@Dejel Collectionè solo la classe base per quali valori restituiti (). L'implementazione della Collezione che restituisce è ancora controllata dal LinkedHashMap. Nel LinkedHashMapcaso, sta restituendo LinkedValuesun'istanza, una classe privata all'interno di LinkedHashMap.java.
Powerlord,

2
Nel mio caso il keyset di LinkedHashMap NON è nell'ordine rappresentato nella mappa. Molto perplesso da questo.
Amalgovinus,

2
Grazie per il collegamento alla documentazione (da 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.
LarsH,

11

Guardando la fonte, sembra che lo sia. keySet(), values()e entrySet()tutti usano lo stesso iteratore di voce internamente.


1
Sarebbe bello avere un collegamento ai repository, ma sono pigro :-) e, naturalmente, non è garanzia di compatibilità con il futuro.
Ciro Santilli 13 冠状 病 六四 事件 法轮功

6

Non essere confuso con LinkedHashMap.keySet()e LinkedHashMap.entrySet()restituire Set e quindi non dovrebbe garantire l'ordinazione!

Setè un'interfaccia con HashSet, TreeSetecc. , le sue implementazioni. L' HashSetimplementazione Setdell'interfaccia non garantisce l'ordinazione. Ma lo TreeSetfa. AncheLinkedHashSet fa .

Pertanto dipende da come Setè stato implementato LinkedHashMapper 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 Setie 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 LinkedHashMape confrontalo con quello di HashMapcui evidenzia la differenza principale tra HashMape LinkedHashMap.


4
Sebbene questa risposta presenti sicuramente informazioni utili, in realtà non risponde alla domanda. In pratica sta dicendo che POSSONO avere un ordine di iterazione prevedibile.
Tuupertunut,

5

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.


0

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.


Vuoi dire entrySet () garantisce l'ordine, con keySet () no?
user256239,

1
@kknight: non ne sono sicuro. il javadoc afferma: "Questo elenco collegato definisce l'ordine di iterazione, che è normalmente l'ordine in cui le chiavi sono state inserite nella mappa (ordine di inserzione).". Tuttavia, i JavaDocs per JDK sono molto ambigui in generale.
Uri,

5
Se anche entrySet () non garantisce l'ordine di iterazione, qual è la differenza tra LinkedHashMap e HashMap? Come possiamo trarre vantaggio dall'ordine di iterazione prevedibile in un'istanza di LinkedHashMap?
user256239,

1
Certamente è documentato. La risposta è completamente errata
Marchese di Lorne,

-3

Guardando l'interfaccia restituisce una semplice Sete 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.


3
Guardando più da vicino alla documentazione, ci sono davvero garanzie. Come qualcuno ha già scritto, questo è il punto centrale di questa lezione.
glglgl,

-4

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.


6
L'intero scopo della LinkedHashMapclasse è 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.
zakinster,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.