Quiero traducir una Lista de objetos en un Mapa usando los flujos y lambdas de Java 8.
Así es como lo escribiría en Java 7 y a continuación.
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;
}
Puedo lograr esto fácilmente usando Java 8 y Guava, pero me gustaría saber cómo hacerlo sin Guava.
En guayaba:
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();
}
});
}
Y guayaba con 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
fuente
fuente
Maps.uniqueIndex(choices, Choice::getName)
.Seq
de la biblioteca JOOL (que recomendaría a cualquiera que use Java 8), también puede mejorar la brevedad con:seq(choices).toMap(Choice::getName)
it -> it
me uso .Function.identity()
se usa aquí principalmente porque se usa en la documentación referenciada y eso era todo lo que sabía sobre lambdas en el momento de escribir estoSi NO se garantiza que su clave sea única para todos los elementos de la lista, debe convertirla en un en
Map<String, List<Choice>>
lugar de unMap<String, Choice>
fuente
Multimaps
método de es una mejor opción? Puede ser un inconveniente ya que no devuelve unMap
Objeto.Úselo
getName()
como la clave yChoice
como el valor del mapa:fuente
Collectors.toMap(Choice::getName,c->c)
(2 caracteres más cortos)choices.stream().collect(Collectors.toMap(choice -> choice.getName(),choice -> choice));
primera función para la tecla, la segunda función para el valorc -> c
peroFunction.identity()
lleva más información semántica. Usualmente uso una importación estática para poder usarlaidentity()
Aquí hay otro en caso de que no desee utilizar Collectors.toMap ()
fuente
Collectors.toMap()
o nuestro propio HashMap como lo mostró en el ejemplo anterior?La mayoría de las respuestas enumeradas, pierden un caso cuando la lista tiene elementos duplicados . En ese caso la respuesta arrojará
IllegalStateException
. Consulte el siguiente código para manejar los duplicados de la lista también:fuente
fuente
Por ejemplo, si desea convertir campos de objeto para asignar:
Objeto de ejemplo:
Y la operación convierte Lista a Mapa:
fuente
Si no le importa usar bibliotecas de terceros, la biblioteca cyclops-react lib de AOL (revelación de que soy colaborador) tiene extensiones para todos los tipos de colección JDK , incluidos List y Map .
fuente
Estaba tratando de hacer esto y descubrí que, usando las respuestas anteriores, cuando usaba
Functions.identity()
la clave del Mapa, tenía problemas con el uso de un método local comothis::localMethodName
que realmente funcionaba debido a problemas de tipeo.Functions.identity()
en realidad hace algo al escribir en este caso, por lo que el método solo funcionaría al devolverObject
y aceptar un parámetro deObject
Para resolver esto, terminé abandonando
Functions.identity()
y usandos->s
lugar.Entonces, mi código, en mi caso para enumerar todos los directorios dentro de un directorio, y para cada uno usar el nombre del directorio como la clave del mapa y luego llamar a un método con el nombre del directorio y devolver una colección de elementos, se ve así:
fuente
Puede crear una secuencia de los índices utilizando un IntStream y luego convertirlos en un mapa:
fuente
Escribiré cómo convertir la lista al mapa usando genéricos e inversión de control . ¡Solo método universal!
Tal vez tenemos una lista de enteros o una lista de objetos. Entonces la pregunta es la siguiente: ¿cuál debería ser la clave del mapa?
crear interfaz
ahora usando inversión de control:
Por ejemplo, si tenemos objetos de libro, esta clase es elegir clave para el mapa
fuente
Yo uso esta sintaxis
fuente
groupingBy
crea unMap<K,List<V>>
, no unMap<K,V>
.String getName();
(no Entero)fuente
Esto se puede hacer de 2 maneras. Deje que la persona sea la clase que vamos a usar para demostrarlo.
Dejar personas sean la lista de personas que se convertirán al mapa
1.Utilizando Foreach simple y una expresión Lambda en la lista
2.Utilizando Collectors on Stream definidos en la Lista dada.
fuente
Es posible usar transmisiones para hacer esto. Para eliminar la necesidad de usar explícitamente
Collectors
, es posible importartoMap
estáticamente (como lo recomienda Effective Java, tercera edición).fuente
Aquí hay una solución de StreamEx
fuente
Incluso sirve este propósito para mí,
fuente
Si cada nuevo valor para el mismo nombre de clave tiene que ser anulado:
Si todas las opciones tienen que agruparse en una lista para un nombre:
fuente
fuente
Como alternativa a
guava
uno, puede usar kotlin-stdlibfuente
Clave duplicada AA {12 = ASDFASDFASDF, 7 = EEDDDAD, 4 = CCCC, 3 = BBB, 2 = AA}
fuente