La différence entre map () et flatMap ()

La différence entre map () et flatMap ()

1. Vue d'ensemble

Les APImap() etflatMap() proviennent de langages fonctionnels. Dans Java 8, vous pouvez les trouver dansOptional, Stream et dansCompletableFuture (although sous un nom légèrement différent).

Streams représente une séquence d'objets, tandis que les options sont des classes qui représentent une valeur qui peut être présente ou absente. Parmi les autres opérations agrégées, nous avons les méthodesmap() etflatMap().

Bien que les deux aient les mêmes types de retour,, ils sont assez différents. Expliquons ces différences en analysant quelques exemples de flux et d'options.

Lectures complémentaires:

Itérer sur une carte en Java

Apprenez différentes manières de parcourir les entrées d'une carte en Java.

Read more

Sérialisation et désérialisation de cartes avec Jackson

Guide rapide et pratique sur la sérialisation et la désérialisation de Java Maps à l'aide de Jackson.

Read more

Comment stocker des clés en double dans une carte en Java?

Un guide rapide et pratique pour gérer les clés en double en utilisant plusieurs cartes en Java.

Read more

2. Carte et Flatmap dans les options

La méthodemap() fonctionne bien avecOptional - si la fonction renvoie le type exact dont nous avons besoin:

Optional s = Optional.of("test");
assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));

Cependant, dans des cas plus complexes, nous pourrions recevoir une fonction qui renvoie également unOptional. Dans de tels cas, l'utilisation demap() conduirait à une structure imbriquée, car l'implémentation demap() effectue un encapsulation supplémentaire en interne.

Voyons un autre exemple pour mieux comprendre cette situation:

assertEquals(Optional.of(Optional.of("STRING")),
  Optional
  .of("string")
  .map(s -> Optional.of("STRING")));

Comme nous pouvons le voir, nous nous retrouvons avec la structure imbriquéeOptional<Optional<String>>. Bien que cela fonctionne, elle est assez lourde à utiliser et ne fournit aucune sécurité nulle supplémentaire, il est donc préférable de garder une structure plate.

C'est exactement ce queflatMap() nous aide à faire:

assertEquals(Optional.of("STRING"), Optional
  .of("string")
  .flatMap(s -> Optional.of("STRING")));

3. Carte et Flatmap dans les flux

Les deux méthodes fonctionnent de la même manière pourOptional.

La méthodemap() enveloppe la séquence sous-jacente dans une instanceStream, tandis que la méthodeflatMap() permet d'éviter la structure imbriquéeStream<Stream<R>>.

Dans l'exemple suivant,map() produit unStream constitué des résultats de l'application de la méthodetoUpperCase() aux éléments de l'entréeStream:

List myList = Stream.of("a", "b")
  .map(String::toUpperCase)
  .collect(Collectors.toList());
assertEquals(asList("A", "B"), myList);

map() fonctionne plutôt bien dans un cas aussi simple, mais que se passe-t-il si nous avons quelque chose de plus complexe comme une liste de listes en entrée.

Voyons voir comment ça fonctionne:

List> list = Arrays.asList(
  Arrays.asList("a"),
  Arrays.asList("b"));
System.out.println(list);

Cet extrait de code imprime une liste de listes[[a], [b]]. Maintenant, utilisons unflatMap():

System.out.println(list
  .stream()
  .flatMap(Collection::stream)
  .collect(Collectors.toList()));

Le résultat d'un tel extrait de code sera aplati à[a, b].

TLa méthodeflatMap() aplatit d'abord l'entréeStream deStreams en unStream deStrings (pour en savoir plus sur l'aplatissement, voir learticle) s). Par la suite, il fonctionne de manière similaire à la méthodemap().

4. Conclusion

Java 8 nous donne la possibilité d'utiliser les méthodesmap() etflatMap() qui étaient à l'origine utilisées dans les langages fonctionnels.

Nous pouvons les invoquer surStreams et Optionals. Ces méthodes nous aident à obtenir des objets mappés en appliquant la fonction de mappage fournie.

Comme toujours, vous pouvez consulter les exemples fournis dans cet articleover on GitHub.