0Pricing
Java Academy · Leçon

Transformer des Optional : map et flatMap

Enchaînez les transformations avec map et flatMap pour traiter des valeurs sans vérifier les valeurs nulles.

Transformer des Optional : map et flatMap est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Transformer des Optional : map et flatMap

map() transforme la valeur contenue dans un Optional si elle est présente. flatMap() évite les Optional imbriqués lorsque la transformation renvoie elle-même un Optional.

map : transformer la valeur

map(Function) applique la fonction à la valeur si elle est présente, puis encapsule le résultat dans un nouvel Optional. Il renvoie un Optional vide si l’Optional d’origine était vide.

import java.util.Optional;

Optional<String> name = Optional.of("alice");

Optional<String> upper = name.map(String::toUpperCase);
System.out.println(upper.get()); // ALICE

Optional<Integer> length = name.map(String::length);
System.out.println(length.get()); // 5

// Empty in → empty out
Optional<String> empty = Optional.<String>empty().map(String::toUpperCase);
System.out.println(empty.isPresent()); // false

Enchaîner des appels à map

Plusieurs appels à map permettent d’enchaîner proprement les transformations sans vérifications d’absence imbriquées.

import java.util.Optional;

record Address(String city, String country) {}
record User(String name, Address address) {}

User user = new User("Alice", new Address("New York", "US"));

// Chain of maps — safe even if any step returns null
Optional<String> city = Optional.ofNullable(user)
    .map(User::address)
    .map(Address::city)
    .map(String::toUpperCase);

System.out.println(city.orElse("Unknown")); // NEW YORK

flatMap : éviter Optional<Optional>

Si votre fonction de mappage renvoie Optional, utilisez flatMap pour conserver un Optional plat plutôt qu’un Optional<Optional> imbriqué.

import java.util.Optional;

record User(String name, Optional<String> email) {}

User u = new User("Bob", Optional.of("bob@example.com"));

// map returns Optional<Optional<String>> — ugly!
Optional<Optional<String>> nested = Optional.of(u).map(User::email);

// flatMap flattens: Optional<String>
Optional<String> flat = Optional.of(u).flatMap(User::email);
System.out.println(flat.get()); // bob@example.com

flatMap en pratique : chaîne de dépôts

Modèle courant : enchaîner des recherches dans des dépôts, chacune renvoyant un Optional.

import java.util.Optional;

record Order(long id, long userId, double total) {}
record User(long id, String name, String email) {}

static Optional<Order> findOrder(long orderId) {
    return orderId == 1 ? Optional.of(new Order(1, 42, 99.99)) : Optional.empty();
}
static Optional<User> findUser(long userId) {
    return userId == 42 ? Optional.of(new User(42, "Alice", "a@co.com")) : Optional.empty();
}

Optional<String> email = findOrder(1)
    .flatMap(o -> findUser(o.userId()))
    .map(User::email);

System.out.println(email.orElse("Not found")); // a@co.com

Résumé de map et flatMap

Choisir entre map et flatMap :

  • Utilisez map lorsque la fonction renvoie une valeur simple (String, Integer)
  • Utilisez flatMap lorsque la fonction renvoie un Optional
import java.util.Optional;

// map: T → R
Optional.of("hello").map(String::toUpperCase);       // Optional<String>
Optional.of("42").map(Integer::parseInt);             // Optional<Integer>

// flatMap: T → Optional<R>
Optional.of("42").flatMap(s -> {
    try { return Optional.of(Integer.parseInt(s)); }
    catch (NumberFormatException e) { return Optional.empty(); }
}); // Optional<Integer> (not Optional<Optional<Integer>>)

Analyser en toute sécurité avec flatMap

Modèle pratique : encapsuler dans Optional, à l’aide de flatMap, les opérations risquées susceptibles d’échouer.

import java.util.Optional;

static Optional<Integer> tryParseInt(String s) {
    try { return Optional.of(Integer.parseInt(s)); }
    catch (NumberFormatException e) { return Optional.empty(); }
}

Optional<String> input = Optional.of("123");
Optional<Integer> parsed = input.flatMap(JavaOptional::tryParseInt);
System.out.println(parsed.map(n -> n * 2).orElse(-1)); // 246

Optional<String> bad = Optional.of("abc");
Optional<Integer> failed = bad.flatMap(JavaOptional::tryParseInt);
System.out.println(failed.orElse(-1)); // -1

Collecter des Optional

Filtrez et mappez un flux d’Optional afin de ne collecter que les valeurs présentes.

import java.util.*;
import java.util.stream.*;

List<String> inputs = List.of("10", "abc", "25", "nope", "7");

List<Integer> numbers = inputs.stream()
    .flatMap(s -> {
        try { return Stream.of(Integer.parseInt(s)); }
        catch (NumberFormatException e) { return Stream.empty(); }
    })
    .collect(Collectors.toList());

System.out.println(numbers); // [10, 25, 7]

Parcourir des objets imbriqués

map et flatMap permettent de parcourir en toute sécurité un graphe d’objets profond sans vérifications d’absence fastidieuses.

import java.util.Optional;

record Company(String name, Optional<Address> address) {}
record Address(String city, Optional<String> zipCode) {}

Company company = new Company(
    "Acme Corp",
    Optional.of(new Address("Austin", Optional.of("78701")))
);

String zip = Optional.of(company)
    .flatMap(Company::address)
    .flatMap(Address::zipCode)
    .orElse("N/A");

System.out.println(zip); // 78701

map pour convertir les types

map est idéal pour convertir le type des valeurs d’un Optional, par exemple pour analyser, formater ou extraire un sous-champ.

import java.util.Optional;
import java.time.LocalDate;

// Parse a date from String safely
static Optional<LocalDate> parseDate(String s) {
    try { return Optional.of(LocalDate.parse(s)); }
    catch (Exception e) { return Optional.empty(); }
}

Optional<String> dateStr = Optional.of("2024-06-15");
Optional<Integer> year = dateStr
    .flatMap(JavaOptional::parseDate)
    .map(LocalDate::getYear);

System.out.println(year.orElse(-1)); // 2024

Construire des pipelines

La combinaison de filter, map et flatMap permet de construire des pipelines de données expressifs qui gèrent l’absence à chaque étape sans vérifications explicites.

import java.util.Optional;

record Product(String sku, String category, boolean inStock, double price) {}

static Optional<Product> findProduct(String sku) {
    if ("LAPTOP-1".equals(sku))
        return Optional.of(new Product("LAPTOP-1", "Electronics", true, 999.99));
    return Optional.empty();
}

Optional<String> priceTag = findProduct("LAPTOP-1")
    .filter(Product::inStock)
    .filter(p -> p.price() < 2000)
    .map(p -> String.format("%s: $%.2f", p.sku(), p.price()));

System.out.println(priceTag.orElse("Not available")); // LAPTOP-1: $999.99

Vérification rapide

Quand devez-vous utiliser flatMap plutôt que map sur un Optional ?

Récapitulatif : transformer des Optional avec map et flatMap

Points essentiels :

  • map() transforme la valeur si elle est présente, puis encapsule le résultat dans un Optional
  • flatMap() s’utilise avec les fonctions qui renvoient un Optional et évite les Optional imbriqués
  • Enchaînez plusieurs map pour effectuer des transformations en plusieurs étapes sans vérifications d’absence
  • Utilisez flatMap pour enchaîner des appels de dépôt ou de service qui renvoient un Optional
  • Combinez filter, map et flatMap pour construire des pipelines de données sûrs en présence d’absences
  • Utilisez flatMap Optional::stream pour intégrer des Optional aux pipelines de flux

Questions Fréquemment Posées

La leçon « Transformer des Optional : map et flatMap » est-elle gratuite ?

Oui — le texte complet de « Transformer des Optional : map et flatMap » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Transformer des Optional : map et flatMap » ?

Enchaînez les transformations avec map et flatMap pour traiter des valeurs sans vérifier les valeurs nulles. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Transformer des Optional : map et flatMap » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Pourquoi Optional existe
  2. Créer et inspecter des Optional
  3. Transformer des Optional : map et flatMap
  4. Bonnes pratiques avec Optional
← Retour à Java Academy