Eu usei LinkedHashMap
porque é importante a ordem em que as chaves foram inseridas no mapa.
Mas agora quero obter o valor da chave em primeiro lugar (a primeira entrada inserida) ou a última.
Deveria haver um método como first()
e last()
ou algo assim?
Preciso ter um iterador para obter apenas a primeira entrada de chave? Por isso eu usei LinkedHashMap
!
Obrigado!
java
dictionary
linkedhashmap
maiky
fonte
fonte
Respostas:
A semântica de
LinkedHashMap
ainda é a de um mapa, e não a de aLinkedList
. Ele mantém a ordem de inserção, sim, mas isso é um detalhe de implementação, e não um aspecto de sua interface.A maneira mais rápida de obter a "primeira" entrada ainda é
entrySet().iterator().next()
. É possível obter a "última" entrada, mas isso implica na iteração de toda a entrada definida, ligando.next()
até você chegar à última.while (iterator.hasNext()) { lastElement = iterator.next() }
edit : No entanto, se você estiver disposto a ir além da API do JavaSE, o Apache Commons Collections terá sua própria
LinkedMap
implementação, que possui métodos comofirstKey
elastKey
, que fazem o que você está procurando. A interface é consideravelmente mais rica.fonte
mylinkedmap.entrySet().iterator().next()
complexidade de tempo? É O (1)?Você pode tentar fazer algo como (para obter a última entrada):
fonte
T last = null ; for( T item : linkedHashMap.values() ) last = item;
Ou algo assim. É O (N) no tempo, mas O (1) na memória.Sei que cheguei tarde demais, mas gostaria de oferecer algumas alternativas, não algo extraordinário, mas alguns casos que nenhum deles mencionou aqui. Caso alguém não se importe tanto com eficiência, mas queira algo com mais simplicidade (talvez encontre o último valor de entrada com uma linha de código), tudo isso será bastante simplificado com a chegada do Java 8 . Eu forneço alguns cenários úteis.
Por uma questão de integridade, comparo essas alternativas com a solução de matrizes que já foram mencionadas neste post por outros usuários. Resumo todos os casos e acho que seriam úteis (quando o desempenho é importante ou não), especialmente para novos desenvolvedores, sempre depende da questão de cada problema
Alternativas possíveis
Uso do método Array
Peguei na resposta anterior para fazer as comparações a seguir. Esta solução pertence a @feresr.
Uso do método ArrayList
Semelhante à primeira solução com desempenho um pouco diferente
Método de redução
Este método reduzirá o conjunto de elementos até obter o último elemento do fluxo. Além disso, ele retornará apenas resultados determinísticos
Método SkipFunction
Esse método obterá o último elemento do fluxo simplesmente ignorando todos os elementos antes dele
Alternativa Iterável
Aqui está o código fonte completo
Aqui está a saída com desempenho de cada método
fonte
LinkedHashMap
A implementação atual (Java 8) mantém o controle de sua cauda. Se o desempenho for uma preocupação e / ou o mapa for grande em tamanho, você poderá acessar esse campo por meio de reflexão.Como a implementação pode mudar, é provavelmente uma boa ideia também ter uma estratégia de fallback. Convém registrar algo se uma exceção for lançada, para que você saiba que a implementação foi alterada.
Pode parecer com:
fonte
ClassCastException
aocatch
just in casetail
não éEntry
uma subclasse (ou uma implementação futura).Mais uma maneira de obter a primeira e a última entrada de um LinkedHashMap é usar o método "toArray" da interface Set.
Mas acho que iterar sobre as entradas no conjunto de entradas e obter a primeira e a última entrada é uma abordagem melhor.
O uso de métodos de matriz leva ao aviso do formulário "... precisa de conversão desmarcada para se ajustar a ..." que não pode ser corrigido [mas só pode ser suprimido usando a anotação @SuppressWarnings ("desmarcada")].
Aqui está um pequeno exemplo para demonstrar o uso do método "toArray":
fonte
Está um pouco sujo, mas você pode substituir o
removeEldestEntry
método do LinkedHashMap, que pode ser adequado para você como um membro anônimo privado:Assim, você sempre poderá obter a primeira entrada no seu
eldest
membro. Será atualizado sempre que você executar umput
.Também deve ser fácil substituir
put
e definiryoungest
...Tudo falha quando você começa a remover as entradas; não descobri uma maneira de julgar isso.
É muito chato que você não possa ter acesso à cabeça ou à cauda de uma maneira sensata ...
fonte
Talvez algo parecido com isto:
fonte
Sugestão:
fonte
Eu recomendaria usar ConcurrentSkipListMap que tem
firstKey()
elastKey()
métodosfonte
Para o primeiro elemento, use
entrySet().iterator().next()
e pare de iterar após 1 iteração. Para a última, a maneira mais fácil é preservar a chave em uma variável sempre que você fizer um map.put.fonte
Embora linkedHashMap não forneça nenhum método para obter o primeiro, o último ou qualquer objeto específico.
Mas é bastante trivial obter:
Definir al = orderMap.keySet ();
agora usando o iterador em um objeto; você pode obter qualquer objeto.
fonte
Sim, me deparei com o mesmo problema, mas, felizmente, só preciso do primeiro elemento ... - Foi o que fiz para isso.
Se você também precisar do último elemento - eu verificaria como reverter a ordem do seu mapa - armazene-o em uma variável temp, acesse o primeiro elemento no mapa invertido (portanto, seria o seu último elemento), mate o variável temp.
Aqui estão algumas boas respostas sobre como reverter a ordem de um hashmap:
Como iterar o hashmap na ordem inversa em Java
Se você usar a ajuda do link acima, dê votos a eles :) Espero que isso ajude alguém.
fonte
à direita, você deve enumerar manualmente o conjunto de chaves até o final da lista vinculada, recuperar a entrada por chave e retornar essa entrada.
fonte
fonte