Recentemente eu ter uma conversa com um colega sobre o que seria a melhor maneira de converter List
a Map
em Java e se há quaisquer benefícios específicos de fazê-lo.
Quero conhecer a melhor abordagem de conversão e realmente aprecio se alguém puder me orientar.
Essa é uma boa abordagem:
List<Object[]> results;
Map<Integer, String> resultsMap = new HashMap<Integer, String>();
for (Object[] o : results) {
resultsMap.put((Integer) o[0], (String) o[1]);
}
Respostas:
Supondo, é claro, que cada item tenha um
getKey()
método que retorne uma chave do tipo apropriado.fonte
getKey()
para qualquer parâmetro específico?getKey()
foi arbitrário.Com java-8, você poderá fazer isso em uma linha usando fluxos e a
Collectors
classe.Demonstração curta:
Resultado:
Como observado nos comentários, você pode usar em
Function.identity()
vez deitem -> item
, embora eu achei -> i
bastante explícito.E, para completar, observe que você pode usar um operador binário se sua função não for bijetiva. Por exemplo, vamos considerar isso
List
e a função de mapeamento que, para um valor int, calcule o resultado do módulo 3:Ao executar esse código, você receberá um erro dizendo
java.lang.IllegalStateException: Duplicate key 1
. Isso ocorre porque 1% 3 é igual a 4% 3 e, portanto, tem o mesmo valor de chave, dada a função de mapeamento de teclas. Nesse caso, você pode fornecer um operador de mesclagem.Aqui está um que soma os valores;
(i1, i2) -> i1 + i2;
que pode ser substituído com o método de referênciaInteger::sum
.que agora gera:
Espero que ajude! :)
fonte
Function.identity()
vez deitem -> item
Function.identity()
retornat -> t;
.::getKey
.Caso essa pergunta não seja fechada como duplicada, a resposta certa é usar o Google Collections :
fonte
Usando o Java 8, você pode fazer o seguinte:
Value
pode ser qualquer objeto que você usar.fonte
Desde o Java 8, a resposta do @ZouZou usando o
Collectors.toMap
coletor é certamente a maneira idiomática de resolver esse problema.E como essa é uma tarefa tão comum, podemos transformá-la em um utilitário estático.
Dessa forma, a solução realmente se torna uma linha.
E aqui está como você o usaria em
List<Student>
:fonte
A
List
eMap
são conceitualmente diferentes. AList
é uma coleção ordenada de itens. Os itens podem conter duplicatas e um item pode não ter nenhum conceito de identificador exclusivo (chave). UMAMap
possui valores mapeados para chaves. Cada chave pode apontar apenas para um valor.Portanto, dependendo
List
dos itens do seu, pode ou não ser possível convertê-lo em aMap
. OsList
itens do seu não têm duplicatas? Cada item tem uma chave exclusiva? Nesse caso, é possível colocá-los em aMap
.fonte
Alexis já postou uma resposta em Java 8 usando o método
toMap(keyMapper, valueMapper)
. Conforme o documento para a implementação deste método:Portanto, caso estejamos interessados em uma implementação específica da
Map
interface, por exemploHashMap
, podemos usar o formulário sobrecarregado como:Embora o uso de um
Function.identity()
oui->i
seja bom, parece que aoFunction.identity()
invés dei -> i
pode economizar memória, conforme esta resposta relacionada .fonte
Também existe uma maneira simples de fazer isso usando o Maps.uniqueIndex (...) do Googlegoiaba bibliotecas
fonte
Método universal
fonte
converter
parâmetro no método?Sem o java-8, você poderá fazer isso em coleções comuns do Commons e na classe Closure
fonte
Muitas soluções vêm à mente, dependendo do que você deseja obter:
Cada item da lista é chave e valor
Os elementos da lista têm algo para procurá-los, talvez um nome:
Os elementos da lista têm algo para procurá-los e não há garantia de que sejam exclusivos: use o MultiMaps do Google
Dando a todos os elementos a posição como chave:
...
Realmente depende do que você deseja obter.
Como você pode ver nos exemplos, um mapa é um mapeamento de uma chave para um valor, enquanto uma lista é apenas uma série de elementos com uma posição cada. Portanto, eles simplesmente não são convertíveis automaticamente.
fonte
Aqui está um pequeno método que escrevi exatamente para esse fim. Ele usa o Validate do Apache Commons.
Sinta-se livre para usá-lo.
fonte
Você pode aproveitar a API de fluxos do Java 8.
Para mais detalhes, visite: http://codecramp.com/java-8-streams-api-convert-list-map/
fonte
Um exemplo do Java 8 para converter um
List<?>
de objetos emMap<k, v>
:Código copiado de:
https://www.mkyong.com/java8/java-8-convert-list-to-map/
fonte
como já foi dito, em java-8 temos a solução concisa dos coletores:
e também, você pode aninhar vários grupos passando um outro método groupingBy como segundo parâmetro:
Dessa forma, teremos um mapa de vários níveis, assim:
Map<key, Map<key, List<Item>>>
fonte
Usando fluxos java-8
fonte
Eu gosto da resposta do Kango_V, mas acho que é muito complexo. Eu acho que isso é mais simples - talvez muito simples. Se inclinado, você pode substituir String por um marcador Genérico e fazê-lo funcionar para qualquer tipo de Chave.
Usado assim:
fonte
Apache Commons MapUtils.populateMap
Se você não usa o Java 8 e não deseja usar um loop explícito por algum motivo, tente
MapUtils.populateMap
no Apache Commons.MapUtils.populateMap
Digamos que você tenha uma lista de
Pair
s.E agora você quer um mapa da
Pair
chave doPair
objeto.dá saída:
Dito isto, um
for
loop é talvez mais fácil de entender. (Isso abaixo fornece a mesma saída):fonte