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é

\n\n

La programmation fonctionnelle (PF) en Java a cessé d'être une simple tendance à la mode — c'est une partie intégrante du langage moderne depuis la version 8. Pour les développeurs ayant maîtrisé les lambdas de base et le Stream API, vient l'étape où une compréhension de concepts plus profonds est nécessaire : monades, composition de fonctions, évaluations paresseuses et structures de données immuables. Cet article est consacré aux techniques avancées de programmation fonctionnelle en Java, qui aideront à écrire un code plus propre, plus prévisible et thread-safe.

\n\n

1. Composition de fonctions et curryfication

\n\n

En Java, les interfaces fonctionnelles Function, Predicate et Consumer fournissent des méthodes par défaut pour la composition : andThen() et compose(). Cela permet de construire des chaînes de transformations sans créer de variables intermédiaires.

\n\n

Exemple de composition :

\n
import java.util.function.Function;\n\npublic class FunctionComposition {\n    public static void main(String[] args) {\n        Function<String, String> trim = String::trim;\n        Function<String, String> toUpper = String::toUpperCase;\n        Function<String, String> addExclamation = s -> s + "!";\n\n        // Composition : trim -> toUpper -> addExclamation\n        Function<String, String> process = trim.andThen(toUpper).andThen(addExclamation);\n\n        String result = process.apply("  hello world  ");\n        System.out.println(result); // HELLO WORLD!\n    }\n}
\n\n

Curryfication — c'est la transformation d'une fonction à plusieurs arguments en une séquence de fonctions à un seul argument. En Java, cela peut être émulé avec des lambdas imbriquées :

\n\n
import java.util.function.Function;\n\npublic class CurryingExample {\n    // Fonction normale\n    static int add(int a, int b) { return a + b; }\n\n    // Version curryfiée\n    static Function<Integer, Function<Integer, Integer>> curriedAdd = a -> b -> a + b;\n\n    public static void main(String[] args) {\n        // Application partielle\n        Function<Integer, Integer> add5 = curriedAdd.apply(5);\n        System.out.println(add5.apply(3)); // 8\n        System.out.println(add5.apply(10)); // 15\n    }\n}
\n\n

La curryfication est utile pour créer des fonctions spécialisées basées sur des modèles généraux, notamment lors du travail avec des configurations.

\n\n

2. Travail avancé avec le Stream API

\n\n

Le Stream API en Java n'est pas simplement un remplacement des boucles. Comprendre ses capacités avancées permet d'améliorer considérablement les performances et la lisibilité du code.

\n\n

2.1. Flux parallèles et splitteurs

\n

Les flux parallèles utilisent ForkJoinPool. Cependant, leur efficacité dépend de la taille des données et de la nature des opérations. Pour un contrôle personnalisé du parallélisme, on peut utiliser Spliterator.

\n\n
import java.util.Spliterator;\nimport java.util.stream.Stream;\nimport java.util.stream.StreamSupport;\n\npublic class CustomSpliterator {\n    public static void main(String[] args) {\n        // Création d'un flux à partir d'un itérateur avec un splitteur personnalisé\n        Spliterator<Integer> spliterator = new Spliterator<>() {\n            int current = 0;\n            @Override\n            public boolean tryAdvance(java.util.function.Consumer<? super Integer> action) {\n                if (current < 100) {\n                    action.accept(current++);\n                    return true;\n                }\n                return false;\n            }\n            @Override\n            public Spliterator<Integer> trySplit() {\n                // Division la plus simple\n                int mid = current + 50;\n                if (mid >= 100) return null;\n                Spliterator<Integer> prefix = new RangeSpliterator(curre                

Blogs

Book Recommendations