Cómo convertir una lista a un mapa en Java

1. Información general

Convertir la lista en mapa es una tarea común. En este tutorial, cubriremos varias formas de hacer esto.

Asumiremos que cada elemento de la Lista tiene un identificador que se utilizará como clave en el Mapa resultante .

2. Estructura de datos de muestra

En primer lugar, modelemos el elemento:

public class Animal { private int id; private String name; // constructor/getters/setters }

El campo id es único, por lo que podemos convertirlo en la clave.

Comencemos a convertir de la manera tradicional.

3. Antes de Java 8

Evidentemente, podemos convertir una lista en un mapa utilizando métodos básicos de Java:

public Map convertListBeforeJava8(List list) { Map map = new HashMap(); for (Animal animal : list) { map.put(animal.getId(), animal); } return map; }

Probemos la conversión:

@Test public void whenConvertBeforeJava8_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListBeforeJava8(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

4. Con Java 8

A partir de Java 8, podemos convertir una lista en un mapa utilizando flujos y recopiladores :

 public Map convertListAfterJava8(List list) { Map map = list.stream() .collect(Collectors.toMap(Animal::getId, animal -> animal)); return map; }

Nuevamente, asegurémonos de que la conversión se realice correctamente:

@Test public void whenConvertAfterJava8_thenReturnMapWithTheSameElements() { Map map = convertListService.convertListAfterJava8(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

5. Uso de la biblioteca de Guava

Además del núcleo de Java, podemos utilizar bibliotecas de terceros para la conversión.

5.1. Configuración de Maven

En primer lugar, debemos agregar la siguiente dependencia a nuestro pom.xml :

 com.google.guava guava 23.6.1-jre 

La última versión de esta biblioteca siempre se puede encontrar aquí.

5.2. Conversión con Maps.uniqueIndex ()

En segundo lugar, usemos el método Maps.uniqueIndex () para convertir una lista en un mapa :

public Map convertListWithGuava(List list) { Map map = Maps .uniqueIndex(list, Animal::getId); return map; }

Finalmente, probemos la conversión:

@Test public void whenConvertWithGuava_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListWithGuava(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); } 

6. Uso de la biblioteca Apache Commons

También podemos realizar una conversión con elmétodo de la biblioteca Apache Commons.

6.1. Configuración de Maven

En primer lugar, incluyamos la dependencia de Maven:

 org.apache.commons commons-collections4 4.2 

La última versión de esta dependencia está disponible aquí.

6.2. MapUtils

En segundo lugar, haremos la conversión usando MapUtils.populateMap () :

public Map convertListWithApacheCommons2(List list) { Map map = new HashMap(); MapUtils.populateMap(map, list, Animal::getId); return map; }

Por último, asegurémonos de que funcione como se esperaba:

@Test public void whenConvertWithApacheCommons2_thenReturnMapWithTheSameElements() { Map map = convertListService .convertListWithApacheCommons2(list); assertThat( map.values(), containsInAnyOrder(list.toArray())); }

7. Conflicto de valores

Veamos qué sucede si el campo id no es único.

7.1. Lista de Animales Con duplicados Id s

En primer lugar, creemos una lista de animales con ID no únicos :

@Before public void init() { this.duplicatedIdList = new ArrayList(); Animal cat = new Animal(1, "Cat"); duplicatedIdList.add(cat); Animal dog = new Animal(2, "Dog"); duplicatedIdList.add(dog); Animal pig = new Animal(3, "Pig"); duplicatedIdList.add(pig); Animal cow = new Animal(4, "Cow"); duplicatedIdList.add(cow); Animal goat= new Animal(4, "Goat"); duplicatedIdList.add(goat); }

Como se muestra arriba, la vaca y la cabra tienen la misma identificación .

7.2. Comprobando el comportamiento

Java Map‘s put() method is implemented so that the latest added value overwrites the previous one with the same key.

For this reason, the traditional conversion and Apache Commons MapUtils.populateMap() behave in the same way:

@Test public void whenConvertBeforeJava8_thenReturnMapWithRewrittenElement() { Map map = convertListService .convertListBeforeJava8(duplicatedIdList); assertThat(map.values(), hasSize(4)); assertThat(map.values(), hasItem(duplicatedIdList.get(4))); } @Test public void whenConvertWithApacheCommons_thenReturnMapWithRewrittenElement() { Map map = convertListService .convertListWithApacheCommons(duplicatedIdList); assertThat(map.values(), hasSize(4)); assertThat(map.values(), hasItem(duplicatedIdList.get(4))); }

As can be seen, the goat overwrites the cow with the same id.

Unlike that, Collectors.toMap() and MapUtils.populateMap() throw IllegalStateException and IllegalArgumentException respectively:

@Test(expected = IllegalStateException.class) public void givenADupIdList_whenConvertAfterJava8_thenException() { convertListService.convertListAfterJava8(duplicatedIdList); } @Test(expected = IllegalArgumentException.class) public void givenADupIdList_whenConvertWithGuava_thenException() { convertListService.convertListWithGuava(duplicatedIdList); }

8. Conclusion

En este artículo rápido, hemos cubierto varias formas de convertir una lista en un mapa, dando ejemplos con el núcleo de Java, así como con algunas bibliotecas de terceros populares.

Como de costumbre, el código fuente completo está disponible en GitHub.