Accueil / Articles PiApplications. / La plate-forme Java / Le langage

Mise au point des streams Java et des expression lambda.

Une expression lambda n'est pas une classe anonyme même si elle peut s'y substituer. Un stream n'est pas la suite séquentielle d'opérations que le code source présente. Dans ces deux cas, le code source agit comme une sorte de préprocesseur pour le compilateur qui créera dans chaque cas un code d'exécution monolithique agissant comme une boîte noire.

Il n'y a donc plus bi univocité entre une instruction de code source et son expression compilée. Cette bi univocité permet la mise en place de points d'arrêts en programmation itérative. Ici, il n'est plus possible d'arrêter l'exécution du flux entre deux opérations ou au sein d'une expression lambda constituée d'une seule instruction. De même, la mise au point pas-à-pas n'est plus possible car le compilateur considère l'expression lambda ou la séquence d'opérations comme une seule instruction. Si l'écriture du code source est plus aisée, la mise au point semble plus difficile. Heureusement, il existe des moyens simples de retrouver la facilité de mise au point.

La cas des streams.

Intéressons nous à la séquence d'opérations :

List<String> lstSortedWords = reader.lines()
 .flatMap(line -> Stream.of(sLine.split(REGEXP))
 .map(String::toLowerCase)
 .distinct()
 .sort((sLinesL, sLinesR) -> sLinesL.length() – sLinesR.length())
 .collect(Collectors.toList());

Si quelque chose se passe mal au sein d'une opération, il n'est pas possible de savoir laquelle. C'est là qu'intervient l'opération peek. Cette opération transmet en sortie l'élément d'entrée sans se préoccuper de ce qu'en fait le consommateur au passage. Cette opération est donc particulièrement adaptée à la mise au point :

List<String> lstSortedWords = reader.lines()
 .flatMap(line -> Stream.of(sLine.split(REGEXP))
 .peek(System.out::println)
 .map(String::toLowerCase)
 .distinct()
 .sort((sLinesL, sLinesR) -> sLinesL.length() – sLinesR.length())
 .collect(Collectors.toList());

De plus, l'endroit où est positionné l'opération permet de suivre exactement ce qui se passe entre les deux opérations qui l'encadre. L'expression peut même se limiter à un consommateur qui ne fait rien : peek(s -> s). Cette notation permet également de placer un point d'arrêt sur l'opération peek.

Il est également de placer un point d'arrêt sur toute instruction du corps du consommateur lorsque l'on ne souhaite pas (ou que l'on ne peut pas) utiliser un système d'historisation.

Le cas des expressions lambda.

Dans la cas des expressions lambda, il est toujours possible d'utiliser un système d'historisation. Cependat, le plus simple est d'extraire le corps de l'expression et de la placer dans une méthode de la classe en cours de mise au point. Il est alors possible à l'expression lambda d'invoquer cette méthode en tant que référence de méthode.

A l'intérieur du corps de la méthode, il est possible de placer un point d'arrêt qui permettra d'examiner l'état des variables internes y compris celui de l'élément reçu du flux.

(c) PiApplications 2016