Eu quero traduzir uma lista de objetos em um mapa usando fluxos e lambdas do Java 8.
É assim que eu escreveria em Java 7 e abaixo.
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
Posso fazer isso facilmente usando Java 8 e Guava, mas gostaria de saber como fazer isso sem o Guava.
Na goiaba:
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
E Goiaba com Java 8 lambdas.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
java
lambda
java-8
java-stream
Tom Cammann
fonte
fonte
Maps.uniqueIndex(choices, Choice::getName)
.Seq
da biblioteca JOOL (que eu recomendo para qualquer um que use o Java 8), você também pode melhorar a brevidade com:seq(choices).toMap(Choice::getName)
it -> it
me uso .Function.identity()
é usada aqui principalmente porque ele é usado na documentação referida e isso era tudo que eu sabia sobre lambdas no momento da escritaSe NÃO for garantido que sua chave seja exclusiva para todos os elementos da lista, você deve convertê-la em um em
Map<String, List<Choice>>
vez de umMap<String, Choice>
fonte
Multimaps
método goiaba é uma opção melhor? Pode ser um inconveniente, pois não retorna umMap
objeto.Use
getName()
como chave eChoice
ele próprio como o valor do mapa:fonte
Collectors.toMap(Choice::getName,c->c)
(2 caracteres mais curtos)choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
primeira função de chave, segunda função para o valorc -> c
masFunction.identity()
carrega mais informações semânticas. Eu costumo usar uma importação estática para que eu possa usar apenasidentity()
Aqui está outro caso você não queira usar Collectors.toMap ()
fonte
Collectors.toMap()
ou nosso próprio HashMap, como você mostrou no exemplo acima?A maioria das respostas listadas perde um caso em que a lista possui itens duplicados . Nesse caso, a resposta será lançada
IllegalStateException
. Consulte o código abaixo para lidar com duplicatas da lista também:fonte
fonte
Por exemplo, se você deseja converter campos de objetos em mapeamento:
Objeto de exemplo:
E a operação converte Lista em Mapa:
fonte
Se você não se importa em usar bibliotecas de terceiros, a lib cyclops-react da AOL (divulgação eu sou um colaborador) possui extensões para todos os tipos de coleções do JDK , incluindo Lista e Mapa .
fonte
Eu estava tentando fazer isso e descobri que, usando as respostas acima, ao usar
Functions.identity()
a chave do mapa, tive problemas ao usar um método local comothis::localMethodName
de fato, funciona por causa de problemas de digitação.Functions.identity()
realmente faz alguma coisa com a digitação neste caso, então o método só funcionaria retornandoObject
e aceitando um parâmetro deObject
Para resolver isso, acabei abandonando
Functions.identity()
e usandos->s
.Portanto, meu código, no meu caso, para listar todos os diretórios dentro de um diretório, e para cada um deles usar o nome do diretório como a chave do mapa e, em seguida, chamar um método com o nome do diretório e retornar uma coleção de itens, se parece com:
fonte
Você pode criar um fluxo de índices usando um IntStream e depois convertê-los em um mapa:
fonte
Vou escrever como converter lista em mapa usando genéricos e inversão de controle . Apenas método universal!
Talvez tenhamos lista de Inteiros ou lista de objetos. Portanto, a pergunta é a seguinte: qual deve ser a chave do mapa?
criar interface
agora usando inversão de controle:
Por exemplo, se tivermos objetos de livro, essa classe será para escolher a chave do mapa
fonte
Eu uso essa sintaxe
fonte
groupingBy
cria umMap<K,List<V>>
, não umMap<K,V>
.String getName();
(não inteiro)fonte
Isso pode ser feito de duas maneiras. Seja pessoa a classe que vamos usar para demonstrá-la.
Permita que as pessoas sejam a lista de Pessoas a serem convertidas no mapa
1.Usando o foreach simples e uma expressão lambda na lista
2.Usando coletores no fluxo definido na lista fornecida.
fonte
É possível usar fluxos para fazer isso. Para remover a necessidade de usar explicitamente
Collectors
, é possível importartoMap
estaticamente (conforme recomendado por Effective Java, terceira edição).fonte
Aqui está a solução da StreamEx
fonte
Até serve esse propósito para mim,
fonte
Se todo novo valor para o mesmo nome de chave tiver que ser substituído:
Se todas as opções tiverem que ser agrupadas em uma lista para um nome:
fonte
fonte
Como alternativa,
guava
pode-se usar o kotlin-stdlibfonte
Divulgue a chave AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CC0, 3 = BBB, 2 = AA}
fonte