A ordem é garantida para o retorno de chaves e valores de um objeto LinkedHashMap?


162

Eu sei que LinkedHashMaptem uma ordem de iteração previsível (ordem de inserção). O Setdevolvido LinkedHashMap.keySet()e o Collectiondevolvido LinkedHashMap.values()também mantêm esse pedido?


1
Como todas as respostas abordam a questão values(), além disso keySet(), ampliei a questão para incluir isso. Isso significa que mais perguntas podem ser encerradas como duplicatas.
Duncan Jones

Respostas:


226

A interface Mapa fornece três visualizações de coleção , que permitem que o conteúdo de um mapa seja exibido como um conjunto de chaves, coleção de valores ou conjunto de mapeamentos de valores-chave. A ordem de um mapa é definida como a ordem na qual os iteradores nas visualizações de coleção do mapa retornam seus elementos. Algumas implementações de mapas, como a TreeMap classe, oferecem garantias específicas quanto à sua ordem; outros, como a HashMapturma, não.

- Mapa

Essa lista vinculada define a ordem da iteração, que normalmente é a ordem na qual as chaves foram inseridas no mapa ( ordem de inserção ).

- LinkedHashMap

Então, sim, keySet(), values(), e entrySet()(os três pontos de vista de recolha referido) valores de retorno na ordem dos usos da lista ligadas internos. E sim, o JavaDoc Mape o LinkedHashMapgarante.

Esse é o objetivo desta aula, afinal.


8
a iteração no mapa também é feita mais rapidamente usando um LinkedHashMap do que um HashMap.
Thierry

2
values ​​() retorna uma coleção. não é uma lista. como ele mantém isso em ordem?
Dejell

7
@Dejel Collectioné apenas a classe base para quais valores () retornam. A implementação da coleção retornada ainda é controlada pelo LinkedHashMap. No LinkedHashMapcaso, está retornando uma LinkedValuesinstância, uma classe privada dentro do LinkedHashMap.java.
Powerlord

2
O conjunto de chaves de um LinkedHashMap no meu caso NÃO está na ordem representada no mapa. Muito intrigado com isso.
Amalgovinus

2
Obrigado por vincular à documentação (de Map) que vincula explicitamente a ordem de um mapa aos iteradores nas visualizações de coleção do mapa (e esclarece quais são essas visualizações de coleção). Essa foi a peça que faltava para mim.
Larsh

11

Olhando para a fonte, parece que sim. keySet(), values()E entrySet()todos usam a mesma entrada iterador internamente.


1
Seria legal ter um link para os repositórios, mas eu sou preguiçoso :-) e, claro, não é garantia de compatibilidade direta.
Ciro Santilli escreveu:

6

Não se confunda com LinkedHashMap.keySet()e LinkedHashMap.entrySet()retorna conjunto e, portanto, não deve garantir ordenação!

Seté uma interface com HashSet, TreeSetetc, suas implementações. A HashSetimplementação da Setinterface não garante pedidos. Mas TreeSetfaz. Também LinkedHashSetfaz.

Portanto, depende de como Setfoi implementado LinkedHashMappara saber se a referência de retorno do conjunto garantirá o pedido ou não. Eu passei pelo código fonte do LinkedHashMap, fica assim:

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

Assim, o LinkedHashMap / HashMap tem sua própria implementação de Setie KeySet. Portanto, não confunda isso com HashSet.

Além disso, a ordem é mantida pela forma como os elementos são inseridos no balde. Observe o addEntry(..)método de LinkedHashMape compare-o com o HashMapque destaca a principal diferença entre HashMape LinkedHashMap.


4
Embora esta resposta definitivamente apresente informações úteis, na verdade não responde à pergunta. Basicamente, eles podem ter ordem de iteração previsível.
Tuupertunut

5

Você pode assumir isso. O Javadoc diz 'ordem de iteração previsível' e os únicos iteradores disponíveis em um mapa são aqueles para keySet (), entrySet () e valores ().

Portanto, na ausência de qualquer qualificação adicional, claramente se aplica a todos esses iteradores.


0

Como o AFAIK não está documentado, você não pode assumi-lo "formalmente". É improvável, no entanto, que a implementação atual mude.

Se você deseja garantir a ordem, pode iterar sobre o mapa que entra e inseri-los em um conjunto classificado com uma função de ordem de sua escolha, embora você esteja pagando um custo de desempenho, naturalmente.


Você quer dizer que entrySet () garante a ordem, por keySet () não?
User256239

1
@ kknight: Não tenho certeza. o javadoc declara: "Esta lista vinculada define a ordem da iteração, que normalmente é a ordem na qual as chaves foram inseridas no mapa (ordem de inserção).". No entanto, os JavaDocs para o JDK são muito ambíguos em geral.
Uri

5
Se mesmo entrySet () não garante a ordem da iteração, qual é a diferença entre o LinkedHashMap e o HashMap? Como podemos tirar proveito da ordem de iteração previsível em uma instância do LinkedHashMap?
User256239

1
Certamente está documentado. A resposta está completamente incorreta.
Marquês de Lorne

-3

Olhando para a interface, ele retorna um simples Sete não um SortedSet. Portanto, não há garantias.

Antes de assumir uma garantia implícita, observando a implementação (sempre uma má ideia), observe também as implementações em todas as outras implementações Java :)

É melhor criar, por exemplo, um TreeSet com o keySet no construtor.


3
Olhando mais de perto a documentação, há realmente garantias. Como alguém já escreveu, esse é o ponto principal desta aula.
glglgl

-4

Eu não acho que você possa presumir a ordem de keySet () e values ​​().

Posso escrever facilmente uma implementação do LinkedHashMap que retorna keySet () e values ​​() desordenados, desde que cumpra o contrato desses dois métodos definidos no Map e substituídos no HashMap.


6
O objetivo da LinkedHashMapclasse é manter a ordem dos elementos enquanto itera o mapa e esse comportamento é bem especificado. Se você escrever uma subclasse sem cumprir a especificação da classe base, estará fazendo algo muito errado.
Zakinster
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.