Java 8 : Les nouveautés

Déterminer les classes de flux

TESTEZ LINKEDIN LEARNING GRATUITEMENT ET SANS ENGAGEMENT

Tester maintenant Afficher tous les abonnements
Les classes de flux sont accompagnées d'opérations qui permettent l'enchaînement de recherche, de tri, et de transformations des données.

Transcription

Dans cette vidéo nous allons aborder donc les Streams, les flux. Alors les flux dont il est question, c'est absolument pas en rapport avec Input Stream, Output Stream, dont on a l'habitude en Java depuis très longtemps, et il s'agit en fait d'un type d'objets qui est représenté par interface Stream dont nous pouvons rapidement avoir un aperçu dans la documentation interface Stream, qui en fait va permettre l'application d'un certain nombre de méthodes, à travers donc des opérations, qui sont dites soit opérations intermédiaires, comme le filtre ici, qu'on va expliquer plus loin, ou des opérations terminales, qui est en l'occurrence ici-même une opération de réduction. Donc pour mettre en oeuvre le stream, je vais prendre un exemple tout bête avec un conteneur classique, pour bien voir que l'on part de quelque chose de totalement classique en Java. Il s'agit donc d'une liste que je vais instancier sous forme d'une ArrayList, donc de stream, que je vais remplir avec un certain nombre d'informations, donc bien entendu là ce qu'il me réclame, c'est l'import de Java.util.arraylist. Je vais mettre étoile ici puisque j'ai un certain nombre de classes de Java util à récupérer, à commencer d'ailleurs par l'interface stream qui se trouve dans Java util. Donc ici, je vais alimenter ma liste, tout à fait classiquement avec des chaînes de caractères pas très originales, Fabien, Add, je vais mettre, Xavier. Je vais mettre dedans un autre prénom. Et l'utilisation des Streams sur ma liste, sur le conteneur, alors les streams et les conteneurs sont finalement quand même assez reliés. Soit vous obtenez un stream à partir du conteneur, soit vous alimentez un conteneur avec le Stream. C'est un petit peu l'idée. Donc ici je vais obtenir un Stream simple, séquentiel, avec la méthode stream que je trouve sur le conteneur. Si, comme on va le voir plus loin, on veut manipuler un stream parallèle, des flux parallèles, donc qui parallèle des opérations, il faut que j'utilise parallèle stream. Donc ici j'utilise un flux séquentiel, et par exemple sur ce flux je vais appliquer une opération terminale qui est de ForEach. ForEach va donc prendre chacun des éléments et appliquer ce que je vais lui passer en paramètre. Alors c'est ici qu'on va retrouver la notion de références de méthode puisque effectivement, la méthode que je vais appliquer c'est tout simplement le système outprintln, qui, comme vous le savez, s' écrit de cette façon là avec "::", qui est un opérateur de résolution de la portée du println par rapport à out. J'exécute mon code tel qu'il est là et j'obtiens effectivement les éléments dans l'ordre d'insertion du conteneur, donc rien de très original. Là où ça commence à devenir plus intéressant, c'est qu'en fait chacune de ces opérations va pouvoir s'enchaîner, et en l'occurrence ici, je pourrais très bien introduire un tri qui serait fait avant le ForEach. Donc maintenant quand j'exécute, effectivement on a trié. Alors bien entendu trié comment ? On a trié avec un ordre naturel sur les stream, sur les chaînes de caractères, donc on commence avec le T, ensuite le F et ensuite le X. Alors je peux rendre l'espèce de pipe-line un peu plus complexe, parce qu'il s'agit effectivement ici vraiment d'un pipe-line. J'enchaîne des transformations du flux pour chacun des objets. Je dois terminer par une opération terminale, alors terminer par une personne dite terminale c'est pas très original, c'est assez redondant mon affaire, mais un exemple j'enlève le ForEach. Le tri ici n'a pas d'effet, en fait. Tant que je n'ai pas appliqué le ForEach, eh bien le sorted n'a pas d'effet. Vous allez me dire, on voit pas grand-chose pour l'instant. Oui c'est vrai, mais je pourrai montrer l'exemple tout à l'heure, où dans les opérations je fais une trace. Ici c'est normal j'ai pas la trace, mon mais ici donc, même si j'arrive à faire une trace dans une opération intermédiaire, eh bien tant que j'ai pas d'opération terminale, rien ne se passera. On est devant une sorte d'économie. Alors je peux aussi appliquer une autre opération intermédiaire tout à fait intéressante, c'est Map. Alors Map en fait, ça consiste à transformer chacun des éléments que j'ai dans mon flux en un autre élément, dont par exemple, ici, en utilisant une méthode que je référence sur stream toUpperCase. Il me manque juste le to, toUpperCase, donc là je vais aller mettre en majuscule chacune des chaînes de caractères que j'ai dans mon conteneur, puis les trier, puis les afficher. Donc effectivement, quand j'exécute, j'obtiens bien des chaînes de caractères en majuscule. Alors on voit venir la puissance de cette notion de flux; alors il est assez classique d'ailleurs, de présenter différemment l'application sur les flux de cette façon-là. Peut être que cette syntaxe est plus fluide quant à l'application des opérations sur les flux. Alors les opérations peuvent être de différents types : ici une application terminale donc pour afficher pour chaque élément, ici une application d'un tri, pour lequel j'aurais pu fournir la relation d'ordre à appliquer. Ici donc, une opération Map qui transforme tous les éléments du conteneur en appliquant cette fonction là, et je pourrais aussi appliquer donc ici une opération de tri. tout à fait significatif. Donc le tri attend un prédicat, c'est-à-dire une méthode qui répond oui ou non. Est-ce que la chaîne, alors par exemple startWith : est-ce que la chaîne commence par la lettre, on va dire X ? startsWith -faudrait pas que je me trompe de nom de méthode- Voilà, donc là on retrouve les lambda expressions. On va voir donc effectivement que toutes ces opérations appliquées sur les flux sont de très grosses consommatrices de lambda expressions, puisque là les critères de recherche, les critères de filtre, les critères de tri, les méthodes à appliquer, etc, pourraient être soit représentés par des références comme ici, soit bien sûr appliquant des SAM, des objets se référant à des interfaces à méthode unique, soit comme là, utilisant des expressions lambda. Donc j'exécute, et bien uniquement le Xavier. L'ordre des différentes opérations que j'applique peut être tout à fait significatif. Il ne faudra pas l'oublier. Je voudrais signaler aussi l'existence de classes de flux spécifiques : alors spécifiques dans la mesure où ici j'utilise tout simplement des flux sur chaînes de caractères. Ce sont des flux tout à fait classiques. Je pourrais aussi utiliser des classes que sont intStream double Stream et long Stream. Donc la classe intStream me permet de manipuler des flux sur les entiers. Pourquoi? Parce que ces types primitifs sont un petit peu particuliers du point de vue de la manipulation, donc par exemple, je veux les entiers entre 1 et 10. donc intStream Java. util .Stream intStream, pour pouvoir continuer. Là-dessus je vais appliquer le forEach, par exemple. Et je vais tout simplement proposer de faire l'affichage de tous les entiers entre 1 et 10, pour qu'on voie ce que ça donne, pas les parenthèses au niveau de la syntaxe de la référence de méthode. Voilà donc cette classe intStream, dont je prends les valeurs qui me créent un flux automatiquement, des valeurs entre 1 et 10. Pour chaque, j'applique le println. Évidemment je me retrouve avec l'affichage des entiers entre 1 et 10. Enfin, donc on peut imaginer de corréler les conteneurs et les Stream. Effectivement on peut construire un Stream, comme on le voit ici, directement à partir d'un ensemble de valeurs. Par exemple, j'aurais pu construire le flux directement comme ça, avec une liste littérale de chaîne de caractères. Donc directement sur ce flux je peux appliquer mon forEach, par exemple mon forEach avec mon System.out::Println. Donc là je vais faire simplement afficher les différentes valeurs. Et on peut imaginer aussi au contraire donc, construire un conteneur à partir du Stream. En l'occurrence ici, vous trouverez donc sur le flux, une méthode par exemple toArray, qui vous permet d'alimenter un tableau à partir de résultats de votre flux. Donc toArray se retrouve être une opération terminale aussi. Donc toArray aussi que j'affecte à un tableau d'Object. Revoyons la documentation de Stream. Effectivement dans la documentation de stream, vous trouverez, dans la description des différentes méthodes, alors je vais par exemple prendre mon toArray. This is a terminal dans la documentation de stream ce qu' est une opération terminale ou bien une opération intermédiaire donc bien entendu stateful intermediate operation. Alors bien sûr l'ordre de ces différentes opérations va être Je vais donc pouvoir appliquer

Java 8 : Les nouveautés

Découvrez les nouveautés introduites par la version 8 de Java. Voyez les expressions lambda, les références de méthodes, les méthodes par défaut dans les interfaces, etc.

1h44 (21 vidéos)
Aucun commentaire n´est disponible actuellement
Logiciel :
Spécial abonnés
Date de parution :17 août 2015

Votre formation est disponible en ligne avec option de téléchargement. Bonne nouvelle : vous ne devez pas choisir entre les deux. Dès que vous achetez une formation, vous disposez des deux options de consultation !

Le téléchargement vous permet de consulter la formation hors ligne et offre une interface plus conviviale. Si vous travaillez sur différents ordinateurs ou que vous ne voulez pas regarder la formation en une seule fois, connectez-vous sur cette page pour consulter en ligne les vidéos de la formation. Nous vous souhaitons un excellent apprentissage avec cette formation vidéo.

N'hésitez pas à nous contacter si vous avez des questions !