Composition fonctionnelle Java

La composition fonctionnelle est une technique permettant de combiner plusieurs fonctions en une seule fonction qui utilisera les fonctions en interne pour les combiner. Vous pouvez vous-même composer individuellement les fonctions (généralement une ou plusieurs expressions Lambda Java) en une seule fonction, mais Java offre également un support intégré pour la composition fonctionnelle afin de vous faciliter la tâche. Dans ce tutoriel sur la composition fonctionnelle en Java, je vous expliquerai à la fois comment composer vous-même des fonctions à partir de fonctions plus petites et comment utiliser les fonctions intégrées de Java.

Exemple de composition fonctionnelle en Java

Pour commencer, laissez-moi vous montrer un exemple de composition fonctionnelle Java. Voici une fonction unique composée à partir de deux autres fonctions :

Predicate<String> startsWithA = (text) -> text.startsWith("A");
Predicate<String> endsWithX   = (text) -> text.endsWith("x");

Predicate<String> startsWithAAndEndsWithX =
        (text) -> startsWithA.test(text) && endsWithX.test(text);

String  input  = "A hardworking person must relax";
boolean result = startsWithAAndEndsWithX.test(input);
System.out.println(result);

Cet exemple de composition fonctionnelle crée d’abord deux implémentations de Predicate sous la forme de deux expressions lambda. Le premier prédicat renvoie vrai si la chaîne que vous lui passez en paramètre commence par un a (A) majuscule. Le second prédicat renvoie vrai si la chaîne de caractères qui lui est transmise se termine par une minuscule x . Notez que l’interface Predicate contient une seule méthode non implémentée nommée test() qui renvoie un booléen. C’est cette méthode que les expressions lambda implémentent.

Après avoir créé les deux fonctions de base, un troisième prédicat est composé, qui appelle les méthodes test() des deux premières fonctions. Cette troisième fonction renvoie vrai si les deux fonctions de base renvoient vrai, et faux sinon.

Enfin, cet exemple appelle la fonction composée et imprime le résultat. Étant donné que le texte commence par un a (A) majuscule et se termine par un x minuscule, la fonction composée renvoie vrai lorsqu’elle est appelée avec la chaîne « Une personne travailleuse doit se détendre ».

Support de la composition fonctionnelle Java

L’exemple figurant dans la section précédente vous a montré comment composer une nouvelle fonction à partir de deux autres fonctions. Plusieurs interfaces fonctionnelles dans Java intègrent déjà le support de la composition fonctionnelle. La prise en charge de la composition fonctionnelle se présente sous la forme de méthodes par défaut et statiques dans les interfaces fonctionnelles. Pour en savoir plus sur les méthodes par défaut et statiques dans les interfaces, consultez mon tutoriel sur les interfaces Java.

Composition de l’interface Predicate

L’interface Predicate (java.util.function.Predicate) contient quelques méthodes qui vous aident à composer de nouvelles instances Predicate à partir d’autres instances Predicate. Je vais couvrir certaines de ces méthodes dans les sections suivantes.

and()

La méthode Predicate and() est une méthode par défaut. La méthode and() est utilisée pour combiner deux autres fonctions Predicate de la même manière que je l’ai montré au début de ce tutoriel sur la composition fonctionnelle en Java. Voici un exemple de composition fonctionnelle avec la méthode Predicate and() :

Predicate<String> startsWithA = (text) -> text.startsWith("A");
Predicate<String> endsWithX   = (text) -> text.endsWith("x");

Predicate<String> composed = startsWithA.and(endsWithX);

String input = "A hardworking person must relax";
boolean result = composed.test(input);
System.out.println(result);

Cet exemple de composition de Predicate compose un nouveau Predicate à partir de deux autres instances de Predicate en utilisant la méthode and() de l’une des instances de Predicate de base.

Le prédicat composé renverra vrai à partir de sa méthode test() si les deux instances de prédicat à partir desquelles il a été composé renvoient également vrai. En d’autres termes, si Predicate one et Predicate two renvoient tous deux true.

or()

La méthode Predicate or() est utilisée pour combiner une instance de Predicate avec une autre, afin de composer une troisième instance de Predicate. Le prédicat composé renverra vrai si l’une ou l’autre des instances de prédicat dont il est issu renvoie vrai, lorsque leurs méthodes test() sont appelées avec le même paramètre d’entrée que le prédicat composé. Voici un exemple de composition fonctionnelle de prédicat ou() en Java :

Predicate<String> startsWithA = (text) -> text.startsWith("A");
Predicate<String> endsWithX   = (text) -> text.endsWith("x");

Predicate<String> composed = startsWithA.or(endsWithX);

String input = "A hardworking person must relax sometimes";
boolean result = composed.test(input);
System.out.println(result);

Cet exemple de composition fonctionnelle de Predicate or() crée d’abord deux instances de Predicate de base. Ensuite, l’exemple crée un troisième prédicat composé à partir des deux premiers, en appelant la méthode or() sur le premier prédicat et en passant le deuxième prédicat comme paramètre à la méthode or().

Le résultat de l’exécution de l’exemple ci-dessus sera vrai, car la première des deux instances de prédicat utilisées dans le prédicat composé renverra vrai lorsqu’elle sera appelée avec la chaîne de caractères « A hardworking person must relax sometimes ».

Composition de l’interface Function

L’interface Java Function (java.util.function.Function) contient également quelques méthodes qui peuvent être utilisées pour composer de nouvelles instances Function à partir d’instances existantes. Je vais couvrir certaines de ces méthodes dans les sections suivantes.

compose()

La méthode Java Function compose() compose une nouvelle instance de Function à partir de l’instance de Function sur laquelle elle est appelée et de l’instance de Function passée en paramètre à la méthode compose().

La fonction retournée par la méthode compose() appellera d’abord la fonction passée en paramètre à la méthode compose(), puis la fonction sur laquelle la méthode compose() a été appelée. Ceci est plus facile à comprendre avec un exemple, voici donc un exemple de la fonction Java compose() :

Function<Integer, Integer> multiply = (value) -> value * 2;
Function<Integer, Integer> add      = (value) -> value + 3;

Function<Integer, Integer> addThenMultiply = multiply.compose(add);

Integer result1 = addThenMultiply.apply(3);
System.out.println(result1);

Lorsqu’elle est appelée avec la valeur 3, la fonction composée appelle d’abord la fonction add, puis la fonction multiply. Le calcul résultant sera (3 + 3) * 2 et le résultat sera 12.

andThen()

La méthode Java Function andThen() fonctionne à l’inverse de la méthode compose(). Une fonction composée avec andThen() appelle d’abord la fonction sur laquelle andThen() a été appelée, puis la fonction passée en paramètre à la méthode andThen(). Voici un exemple de fonction Java andThen() :

Function<Integer, Integer> multiply = (value) -> value * 2;
Function<Integer, Integer> add      = (value) -> value + 3;

Function<Integer, Integer> multiplyThenAdd = multiply.andThen(add);

Integer result2 = multiplyThenAdd.apply(3);
System.out.println(result2);

Cet exemple crée d’abord une fonction multiply et une fonction add. Ensuite, la méthode andThen() est appelée sur la fonction multiply pour composer une nouvelle fonction, en passant la fonction add comme paramètre à andThen().

L’appel de la fonction composée par andThen() avec la valeur 3 donnera le calcul suivant
3 * 2 + 3 et le résultat sera 9.

Remarque : Comme nous l’avons mentionné au début, andThen() fonctionne à l’inverse de compose(). Par conséquent, appeler a.andThen(b) revient en fait à appeler b.compose(a) .

Laisser un commentaire