2010-05-27 7 views
108

So che LinkedHashMap ha un ordine di iterazione prevedibile (ordine di inserimento). Lo restituito da LinkedHashMap.keySet() e Collection restituito da LinkedHashMap.values() mantiene anche questo ordine?L'ordine è garantito per la restituzione di chiavi e valori da un oggetto LinkedHashMap?

+1

Poiché tutte le risposte risolvono il problema di 'values ​​()' e di 'keySet()', ho ampliato la domanda per includerla. Ciò significa che più domande possono essere chiuse come duplicati di questo. –

risposta

153

L'interfaccia Map fornisce tre viste raccolta, che permettono il contenuto di una mappa che essere visti come un insieme di chiavi, insieme di valori, o un insieme di mappature chiave-valore. L'ordine di una mappa viene definita come l'ordine in cui gli iteratori sulla raccolta della mappa visualizzazioni restituiscono i loro elementi. Alcune implementazioni della mappa , come la classe , forniscono specifiche garanzie sul loro ordine, ; altri, come la classe HashMap, no.

- Map

Questa lista collegata definisce l'iterazione ordinamento, che normalmente è dell'ordine in cui le chiavi sono state introdotte nel mappa (inserimento ordine).

- LinkedHashMap

Quindi, sì, keySet(), values(), e entrySet() (le tre viste di raccolta di cui) i valori restituiti nell'ordine della lista collegata interno utilizza. E sì, il JavaDoc per Map e LinkedHashMap lo garantisce.

Questo è il punto di questa classe, dopo tutto.

+7

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

+0

@Thierry: Sì, avrei dovuto dirlo. Ops. – Powerlord

+1

values ​​() restituisce una raccolta. non una lista. come lo mantiene in ordine? – Dejell

-1

Guardando all'interfaccia restituisce un semplice Set e non uno SortedSet. Quindi non ci sono garanzie.

Prima di assumere una garanzia implicita, cercando in realizzazione (sempre una cattiva idea) anche guardare le implementazioni in tutte le altre implementazioni Java :)

Si potrebbe meglio creare per esempio un TreeSet con il set di tasti nel costruttore .

+2

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

10

Guardando alla fonte, sembra che lo faccia. keySet(), values() e entrySet() utilizzano tutti lo stesso ingresso iteratore internamente.

+1

Sarebbe bello avere un collegamento ai repository, ma sono pigro :-) e, naturalmente, non è garanzia di compatibilità diretta. –

0

AFAIK non è documentato in modo da non poterlo "formalmente" assumere. È improbabile, tuttavia, che l'attuale implementazione cambierebbe.

Se si desidera garantire l'ordine, è possibile eseguire un'iterazione sulle entrate della mappa e inserirle in un set ordinato con una funzione di ordine a scelta, anche se si pagherà un costo di rendimento, naturalmente.

+0

Significa che entrySet() garantisce l'ordine, per keySet() no? – user256239

+0

@kknight: non ne sono sicuro. 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 inserimento).". Tuttavia, i JavaDocs per JDK sono molto ambigui in generale. – Uri

+3

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

4

Si può presumere di si. Javadoc dice "ordine di iterazione prevedibile" e gli unici iteratori disponibili in una mappa sono quelli per keySet(), entrySet() e values ​​().

Quindi in assenza di ulteriori qualifiche è chiaramente inteso applicarsi a tutti quegli iteratori.

-3

Non penso che si possa presumere l'ordine di keySet() e values ​​().

Posso scrivere facilmente un'implementazione di LinkedHashMap che restituisce un valore non ordinato di keySet() e values ​​(), a condizione che rispetti il ​​contratto di questi due metodi definiti in Map e sovrascritto in HashMap.

+5

L'intero scopo della classe 'LinkedHashMap' è di mantenere l'ordine degli elementi mentre si itera la mappa e questo comportamento è ben specificato. Se scrivi una sottoclasse senza rispettare le specifiche della classe base, stai facendo qualcosa di molto sbagliato. – zakinster

4

Non confondersi con LinkedHashMap.keySet() e LinkedHashMap.entrySet() restituendo Set e quindi non dovrebbe garantire l'ordine!

Set è un'interfaccia con HashSet, TreeSet ecc. Le sue implementazioni. L'implementazione HashSet dell'interfaccia Set non garantisce l'ordine. Ma lo fa TreeSet. Anche LinkedHashSet fa.

Pertanto, dipende da come Set è stato implementato in LinkedHashMap per sapere se il riferimento di Set restituito garantirà l'ordine o meno. Sono andato attraverso il codice sorgente di LinkedHashMap, sembra che questo:

private final class KeySet extends AbstractSet<K> {...} 
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...} 

Così LinkedHashMap/HashMap ha una propria implementazione di Set cioè KeySet. Quindi non confondere questo con HashSet.

Inoltre, l'ordine viene mantenuto dal modo in cui gli elementi vengono inseriti nel bucket. Esaminare il metodo addEntry(..) di LinkedHashMap e confrontarlo con quello di HashMap che evidenzia la differenza principale tra HashMap e LinkedHashMap.

+1

Mentre questa risposta presenta sicuramente informazioni utili, in realtà non risponde alla domanda. In pratica si sta dicendo che possono avere un ordine di iterazione prevedibile. – Tuupertunut

Problemi correlati