Java fonctionnel - Optional
Apprendre quand et comment utiliser Optional en Java pour gerer le null-safe flow, map/flatMap/orElse et les bonnes pratiques aux frontieres d'API.
Pourquoi cette etape est importante
null est une source frequente de bugs en production. Optional permet de modeliser explicitement l'absence d'une valeur et d'eviter des NullPointerException cachees.
Idee centrale
Optional<T> signifie : la valeur peut etre presente ou absente.
Optional<String> token = Optional.of("abc");
Optional<String> missing = Optional.empty();
Utilisation :
of(...)si la valeur est garantie non nulleofNullable(...)si la valeur peut etre nulleempty()pour l'absence de valeur
Operations courantes
Optional<String> email = Optional.ofNullable("briac@example.com");
String domain = email
.map(e -> e.substring(e.indexOf("@") + 1))
.orElse("unknown");
System.out.println(domain); // example.com
map: transforme si presentflatMap: chaine des appels qui renvoient deja un OptionalorElse/orElseGet: valeur de secoursorElseThrow: echec explicite
map vs flatMap
La difference cle est la forme du type de retour.
mapapplique une fonctionT -> Ret retourneOptional<R>flatMapapplique une fonctionT -> Optional<R>et retourneOptional<R>(aplati)
Si le mapper renvoie deja un Optional, map cree un niveau imbrique.
Optional<User> user = findUser("briac");
Optional<Optional<String>> wrong = user.map(u -> findCityByUser(u.id()));
Optional<String> correct = user.flatMap(u -> findCityByUser(u.id()));
Pourquoi :
- avec
map, Java enveloppe encore le resultat, doncOptional<Optional<String>> - avec
flatMap, Java evite ce double enveloppement et renvoie un seulOptional<String>
Utilise map quand le mapper renvoie une valeur simple :
Optional<User> user = findUser("briac");
Optional<String> username = user.map(User::username);
Utilise flatMap quand le mapper renvoie deja un Optional :
Optional<User> user = findUser("briac");
Optional<String> city = user.flatMap(u -> findCityByUser(u.id()));
Bonnes pratiques aux frontieres d'API
Bien :
- retourner
Optional<T>pour les methodes de recherche (findById)
A eviter :
- des champs
Optionaldans les entites/DTO Optionalen parametre de methode dans la plupart des cas
orElse vs orElseGet
orElse evalue toujours son argument.
orElseGet evalue la valeur de secours seulement si necessaire.
String value = optional.orElseGet(() -> expensiveFallback());
Prefere orElseGet si le fallback est couteux.
Erreurs frequentes
- utiliser
Optional.get()sans verifier la presence - envelopper tout dans Optional (sur-conception)
- retourner
nullau lieu deOptional.empty()
A retenir
- Utiliser Optional pour modeliser explicitement l'absence
- Composer avec
mapetflatMap - Utiliser
orElseGet/orElseThrowde maniere intentionnelle - Garder Optional aux frontieres d'API/recherche, pas partout