Comment convertir une liste en carte en Java

1. Vue d'ensemble

La conversion de liste en carte est une tâche courante. Dans ce didacticiel, nous aborderons plusieurs façons de procéder.

Nous supposerons que chaque élément de la liste a un identifiant qui sera utilisé comme clé dans la carte résultante .

2. Exemple de structure de données

Tout d'abord, modélisons l'élément:

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

Le champ id est unique, nous pouvons donc en faire la clé.

Commençons à convertir avec la manière traditionnelle.

3. Avant Java 8

Évidemment, nous pouvons convertir une liste en carte en utilisant les méthodes Java de base:

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

Testons la conversion:

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

4. Avec Java 8

À partir de Java 8, nous pouvons convertir une liste en une carte à l' aide de flux et de collecteurs :

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

Encore une fois, assurons-nous que la conversion est effectuée correctement:

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

5. Utilisation de la bibliothèque Guava

Outre le noyau Java, nous pouvons utiliser des bibliothèques tierces pour la conversion.

5.1. Configuration Maven

Tout d'abord, nous devons ajouter la dépendance suivante à notre pom.xml :

 com.google.guava guava 23.6.1-jre 

La dernière version de cette bibliothèque est toujours disponible ici.

5.2. Conversion avec Maps.uniqueIndex ()

Deuxièmement, utilisons la méthode Maps.uniqueIndex () pour convertir une liste en une carte :

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

Enfin, testons la conversion:

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

6. Utilisation de la bibliothèque Apache Commons

Nous pouvons également effectuer une conversion avec leméthode de la bibliothèque Apache Commons.

6.1. Configuration Maven

Tout d'abord, incluons la dépendance Maven:

 org.apache.commons commons-collections4 4.2 

La dernière version de cette dépendance est disponible ici.

6.2. MapUtils

Deuxièmement, nous effectuerons la conversion en utilisant MapUtils.populateMap () :

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

Enfin, assurons-nous que cela fonctionne comme prévu:

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

7. Conflit de valeurs

Vérifions ce qui se passe si le champ id n'est pas unique.

7.1. Liste des animaux avec des identifiants dupliqués

Tout d'abord, créons une liste d' animaux avec des identifiants non uniques :

@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); }

Comme indiqué ci-dessus, la vache et la chèvre ont le même identifiant .

7.2. Vérification du comportement

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

Dans cet article rapide, nous avons couvert différentes façons de convertir une liste en carte, en donnant des exemples avec le noyau Java ainsi que certaines bibliothèques tierces populaires.

Comme d'habitude, le code source complet est disponible à l'adresse over sur GitHub.