Programmation fonctionnelle en Java : techniques avancées et Stream API

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Programmation fonctionnelle en Java : niveau avancé



La programmation fonctionnelle (PF) est un paradigme dans lequel les calculs sont considérés comme des calculs de fonctions mathématiques, évitant les changements d'état et les données mutables. Java, étant un langage orienté objet, a reçu avec la sortie de Java 8 des outils puissants pour la PF : les expressions lambda, l'API Stream et les interfaces fonctionnelles. Au niveau avancé, ces possibilités permettent d'écrire un code plus concis, plus sûr et plus expressif, en particulier lors du travail avec des collections, des opérations asynchrones et la gestion des erreurs.



Dans cet article, nous examinerons les techniques avancées de programmation fonctionnelle en Java : la composition de fonctions, les monades (Optional et CompletableFuture), l'API Stream avec traitement parallèle et le currying.



1. Composition de fonctions et interfaces fonctionnelles



En Java, les interfaces fonctionnelles sont des interfaces avec une seule méthode abstraite (SAM). Les plus couramment utilisées sont : Function<T, R>, Predicate<T>, Consumer<T> et Supplier<T>. L'utilisation avancée inclut la composition de fonctions à l'aide des méthodes andThen() et compose().



Exemple : chaîne de transformations



import java.util.function.Function;

public class FunctionComposition { public static void main(String[] args) { // Fonction : chaîne -> sa longueur Function<String, Integer> lengthFunction = String::length; // Fonction : nombre -> son carré Function<Integer, Integer> squareFunction = x -> x * x;

// Composition : chaîne -> longueur -> carré de la longueur Function<String, Integer> composedFunction = lengthFunction.andThen(squareFunction);

String text = "Hello, Java!"; int result = composedFunction.apply(text); // 12 * 12 = 144 System.out.println("Résultat : " + result); // 144 }}


La méthode andThen() applique d'abord la première fonction, puis la seconde. compose() fait l'inverse : elle applique d'abord la fonction passée en argument, puis la première. Cela permet de construire des chaînes de transformations flexibles et réutilisables.



Exemple pratique : filtrage et transformation d'une liste



import java.util.List;import java.util.function.Function;import java.util.function.Predicate;import java.util.stream.Collectors;

public class PredicateAndFunction { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie", "David", "Eve");

Predicate<String> startsWithA = s -> s.startsWith("A"); Function<String, String> toUpperCase = String::toUpperCase;

List<String> result = names.stream() .filter(startsWithA) .map(toUpperCase) .collect(Collectors.toList());

System.out.println(result); // [ALICE] }}


2. Monades en Java : Optional et CompletableFuture



Une monade est un patron qui encapsule une valeur et fournit des opérations pour la transformer sans déballage explicite. En Java, les monades sont implémentées via Optional (pour la gestion de null) et CompletableFuture (pour les opérations asynchrones).



Optional comme monade

Les méthodes map(), flatMap() et filter() permettent de travailler en chaîne avec l'absence possible de valeur.



import java.util.Optional;

public class OptionalMonad { public static void main(String[] args) { // Création d'un Optional avec une valeur non nulle Optional<String> optional = Optional.of("Hello");

// Chaîne de transformations String result = optional .filter(s -> s.length() > 3) // filtre .m

Blogs

Book Recommendations