Java 8 Streams, une introduction pratique | Jeronemo | Skillshare

Vitesse de lecture


1.0x


  • 0.5x
  • 0.75x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Java 8 Streams, une introduction pratique

teacher avatar Jeronemo

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Introduction

      0:41

    • 2.

      Cas d'utilisation et d'utilisation du flux

      3:28

    • 3.

      Interfaces fonctionnelles et Lambda

      10:48

    • 4.

      Opérations de flux

      1:52

    • 5.

      Fonctionnement intermédiaire : filtre

      1:19

    • 6.

      Fonctionnement du terminal : pourChaque

      1:31

    • 7.

      Opérations intermédiaires : carte

      1:34

    • 8.

      Opérations intermédiaires : flatMap

      2:36

    • 9.

      Opérations intermédiaires : séquentiel et parallèle

      2:48

    • 10.

      Fonctionnement intermédiaire : jeter un oeil

      1:33

    • 11.

      Fonctionnement du terminal : collecter

      4:06

    • 12.

      Fonctionnement du terminal : réduire

      5:11

    • 13.

      Résumé et mot de l'après-midi

      1:31

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

34

apprenants

--

projet

À propos de ce cours

Les flux ont été introduits dans Java 8, mais ils sont tout aussi pertinents dans Java 11, Java 17 et toutes les versions à venir. Ils sont un aspect clé pour devenir un meilleur développeur de Java.

Ce cours vous apprendra tout ce que vous devez savoir sur les flux de Java pour commencer à les utiliser dans vos propres projets. Son objectif est de vous donner un aperçu des possibilités de Streams et de vous permettre de reconnaître les situations dans lesquelles Streams peut être utile. Elle se concentre principalement sur ceux qui n'ont pas ou peu d'expérience avec Streams et lambdas, mais peut également être utilisée comme cours de recyclage sur les opérations les plus couramment utilisées et leur utilisation.

Ce que vous apprendrez dans ce cours :

  • Comment fonctionnent et sont créées les interclasses anonymes, les interfaces fonctionnelles et les lambdas.
  • Comment fonctionnent les flux en général et pourquoi vous devriez les utiliser.
  • Comment fonctionnent les opérations les plus couramment utilisées dans un flux de données.

Les flux sont une étape dans la programmation fonctionnelle. Mastering Streams rend votre code lisible comme une histoire, ce qui le rend d'autant plus readable par vous et par les autres. Il y a des exercices à la fin pour mettre tout en pratique.

À qui s'adresse ce cours :

Tout développeur Java intéressé par Streams, ou la programmation fonctionnelle en général. Alors que le titre mentionne Java 8 (dont la version d'introduction était la version), c'est une excellente compétence pour avoir peu importe la version de Java sur laquelle vous travaillez. Vous devez avoir une compréhension de base de l'utilisation de Java, comme la compilation et l'exécution du code, ainsi que l'extension des cours et l'implémentation des interfaces.

Matériel nécessaire pour ce cours :

Aucun matériel n'est nécessaire pour suivre ce cours. Si vous souhaitez faire les exercices à la fin de votre travail, vous devrez toutefois disposer de JDK 8 ou plus. Une façon de modifier et d'exécuter les fichiers .java est également nécessaire. Cela pourrait être aussi simple que le bloc-notes, mais je recommande d'utiliser un IDE comme IntelliJ ou
Eclipse.That's tout !

Rencontrez votre enseignant·e

Teacher Profile Image

Jeronemo

Enseignant·e

Hey there, welcome to my profile! I have the classical Dutch name Jeroen, but you may call me Jeronemo.

I've been a backend developer for the good part of a decade, dabbing mostly in microservice architecture using REST, Java & Spring Boot, but having worked with loads of other stuff like ADO, Docker, ELK stack, Eureka, Flyway, Gitlab, GWT, Hazelcast, Hibernate, Hoverfly, IntelliJ, Jackson, Jenkins, JIRA, JSON, Junit, Kubernetes, RabbitMQ, Maven, Mockito, Nexus, SOAP, Sonar, SQL, WDSL, XSD & Zuul.

Voir le profil complet

Level: All Levels

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Introduction: Bonjour à tous, bienvenue dans la classe Java eight streams, une introduction pratique. Je m'appelle Journeyman, et dans ce cours, je vais vous expliquer tout sur les streams et leur utilisation. Ce cours est destiné à doser, ayant peu ou pas d' expérience avec les ruisseaux est de la gaze pour vous donner un aperçu de la possibilité des ruisseaux. Vous reconnaissez les situations dans lesquelles les flux peuvent être utiles. Nous allons approfondir l'utilisation des streams et en général. Vous souhaitez les utiliser dans interfaces fonctionnelles et des lambdas. Je vais expliquer les opérations couramment utilisées pour ceux qui ont envie d'une approche plus pratique. Ce cours propose également des exercices pour mettre en pratique les connaissances apprises. Allons-y. 2. Cas d'utilisation et d'utilisation du flux: Utilisation et cas d'utilisation des flux. Les cours d'eau utilisent simplement un cours d'eau pour traiter une collection d'objets. Dans un chapitre ultérieur, nous examinerons plus en détail certaines méthodes spécifiques de traitement d'une collection. Mais pour l'instant, considérez simplement le traitement comme le filtrage, la modification et l'enrichissement des données à collecter. Notez toutefois que les productions utilisées comme entrées pour les flux ne sont pas réellement modifiées par les flux. Au lieu de cela, l'exécution d'un flux nous donne résultats distincts déconnectés de la collection d'origine. Ces étapes de traitement des opérations sont écrites de manière fonctionnellement descriptive. Cela signifie qu'un stream se lit comme une histoire lorsqu'il est fait correctement, ce qui le rend incroyablement utile. Pour mettre cela en valeur. Voici un exemple de méthode classique de filtrage, de collecte, de tri et d'impression de certaines données. J'utilise la même logique écrite dans les streams. Je suis sûr que vous serez capable comprendre les deux côtés un jour, mais je pense que nous sommes tous d'accord pour dire que l'utilisation de streams permet l'utilisation de streams permet de comprendre beaucoup plus facilement ce que fait le code. Alors, vous l'avez. Les flux sont utilisés pour traiter une collection d'articles de manière très raisonnable. Comment fonctionnent les streams ? Comme je viens de le dire, les streams fonctionnent sur une collection d'objets. Vous vous êtes peut-être rendu compte que la collection de mots correspond à une interface. En Java. L'interface trouvée dans le package Java util est notre lien pour travailler avec les flux. La plupart du temps, vous utilisez généralement une liste ou un ensemble pour démarrer un flux qui étend l'interface de collecte. Il existe d'autres moyens de créer un flux. Nous ne les aborderons pas dans ce cours. Vous pouvez les trouver dans les ressources. Avec l'arrivée de Java Eight, une méthode par défaut appelée stream a été ajoutée à l'interface de collecte. Pour ceux qui ne connaissent pas les méthodes par défaut. Les méthodes par défaut vous permettent d'ajouter nouvelles fonctionnalités aux interfaces de vos bibliothèques et de garantir la compatibilité binaire avec le code écrit pour les anciennes versions des interfaces. Ce flux de méthode par défaut renvoie une instance du flux coûte à la classe d'API centrale qui nous permet de travailler avec eux. Après avoir créé le flux, vous pouvez désormais enchaîner les opérations et exécuter le flux. Nous en reparlerons plus tard. Résumons ce que nous avons appris jusqu'à présent. Les flux sont utilisés pour traiter une collection d'éléments de manière très lisible. Les flux ne modifient pas cette collection source, mais créent un résultat distinct déconnecté de la collection d'origine. L'interface de flux est le coût central de l'API lié à l'utilisation des flux. Tout ce qui étend ou implémente l'interface de collecte possède une méthode de flux par défaut pour interagir avec la classe d'API centrale des ensembles. 3. Interfaces fonctionnelles et Lambda: Interfaces fonctionnelles et lambdas. Avant de commencer à parler des opérations de streaming, nous devons parler des conditions préalables l'utilisation de strips. Les Lambdas. Les lambdas sont essentiellement des classes internes anonymes, des interfaces fonctionnelles dont le compilateur Java indique implicitement les informations nécessaires. Commençons par le début. Classes internes anonymes. Lorsque vous implémentez une interface, vous allez implémenter toutes ses méthodes. Voici un exemple où vous créez classe implémentée et l'instanciez. Nous avons ici une interface appelée mon interface avec l'impression. Une méthode importante est implémentée par mon interface. Mais que se passe-t-il si j'ai besoin d'une implémentation légèrement différente des impressions, une méthode importante. Dans ce scénario, je devrais créer une autre classe qui implémente mon interface. Encore une fois. Imaginez que si vous avez dix variances différentes, elles seront bientôt encombrées. C'est un signal pour les classes internes anonymes. La classe interne anonyme est une extension d'une classe. Une implémentation d'une interface sans nom, donc anonyme. Nous allons nous concentrer sur la partie S de l' interface. C'est la partie la plus importante dans le contexte des streams. Comme ils n'ont pas de nom, nous ne pouvons pas créer d'instance de la classe interne anonyme à elle seule. Au lieu de cela, vous devez déclarer et instancier la classe interne anonyme dans une seule expression. Cette expression se présente comme suit, ce qui se traduit par ce qui suit. Lors de la création de la version anonyme de classe interne de mes informations d'interface. Comme vous pouvez le constater, nous avons créé une instance de mon interface sans avoir besoin d' une classe implémentant l'interface. Et si je souhaite ajouter une nouvelle implémentation de mon interface, je peux simplement le faire. Voilà, nous l'avons. Les classes internes anonymes peuvent être utilisées pour implémenter une interface sans avoir à définir une classe rigide. Vous pouvez simplement les créer à la volée. Interfaces fonctionnelles. L'interface fonctionnelle n' est qu'une interface , sauf qu'elle ne contient qu' une seule méthode qui doit être mise en œuvre. Toute interface répondant à ces critères est une interface fonctionnelle. Tout comme notre exemple d'interface tout à l'heure. Bien que cela ne soit pas nécessaire, vous pouvez ajouter l' annotation de l'interface fonctionnelle pour montrer votre intention. En prime, le compilateur lancera une exception lors de la compilation lorsqu'il ne s'agit pas réellement d'une interface fonctionnelle lors de l'utilisation de cette annotation. Passons en revue les interfaces fonctionnelles les plus couramment utilisées lors de l'utilisation de flux. premier est le fournisseur qui a admis les gets. Il ne s'attend à aucun argument, mais renvoie quelque chose. Le fournisseur vous fournit quelque chose, généralement un objet neuf, vide et propre. On pourrait le voir comme une usine. Le suivant est le prédicat. Avec admis. Elle attend un argument, l'évalue et renvoie une valeur booléenne. Comme son nom l'indique, il s'agit essentiellement d'un test. L'argument t répond-il aux critères donnés par oui ou par non ? consommateur avec ses méthodes accepte, accepte un argument, en fait quelque chose, mais ne renvoie rien, consommant littéralement les arguments au cours du processus. Le consommateur de vélo fait la même chose que le consommateur, sauf qu'il s'attend à deux arguments. La fonction et ses méthodes s'appliquent. Il s'attend à une dispute, il en fait quelque chose. Et les retours en arguments mappent ou enrichissent essentiellement l'argument dans le processus, les arguments r et t peuvent être de la même classe. La fonction by fait la même chose que la fonction. Excepted attend deux arguments, T et U en font quelque chose. Les retours sont exactement comme la fonction. Les arguments peuvent être de la même classe si nécessaire. Et sur cette note, nous arrivons à la dernière interface fonctionnelle commune. Opérateur binaire. L'opérateur binaire est une extension de la fonction by où T, U et R sont exactement la même classe. Assurez-vous d'avoir une bonne compréhension des interfaces fonctionnelles en général et de ces interfaces courantes avant de continuer. Cela vous aidera à comprendre plus facilement les opérations lambdas et les flux de données. Expressions lambda. Les classes internes anonymes d' interfaces fonctionnelles dont le compilateur Java connaît implicitement les informations nécessaires sont les plus regroupées. Nous savons maintenant ce qu' est une classe interne anonyme et comment nous devons encore implémenter toutes les méthodes d'une interface. Nous remarquons que les interfaces fonctionnelles sont des interfaces normales, sauf qu'elles n'ont qu' une seule méthode à implémenter. Comme une interface fonctionnelle ne possède qu'une seule méthode, le compilateur est capable de comprendre de nombreuses informations en fonction du contexte. En tant que développeur, vous pouvez omettre ces informations. Cela permet au compilateur de savoir que vous omettez des choses. Problèmes de syntaxe Lambda. Nous allons commencer par une classe interne anonyme irrégulière et convertir en une expression lambda complète , pièce par pièce. Ou utilisez le prédicat d'interface fonctionnelle pour tester si un entier donné est supérieur à un. En surveillant le signe égal, nous avons remarqué le nom de l' interface que nous implémentons. Le corps de la classe interne anonyme, la signature de la méthode et le corps des méthodes que nous implémentons. Regardez de plus près le nom de l'interface et la signature de la méthode. Voyez-vous comment le compilateur pourrait déduire ces connaissances ? Remarquez que les noms d'interface se trouvent déjà sur le côté gauche des instructions Equal. Remarquez que puisque le prédicat est une interface fonctionnelle, il n'y a qu'une seule méthode à implémenter. Nous savons donc déjà quelles méthodes nous mettons en œuvre. Ces deux types d' informations peuvent être déduits par le compilateur. Notre première étape consiste à écrire ceci en utilisant la syntaxe groupée, la flèche. Avec elle. Nous allons supprimer le nom de l' interface, le nom de la méthode. Cela a déjà l'air beaucoup plus propre, non ? Nous voyons ici l'entrée des méthodes, l'entier sur le côté gauche de la flèche et le corps de la méthode sur le côté droit. Mais il y a encore des informations que nous pouvons omettre dans ce cas. Comme il existe une méthode unique et le compilateur connaît sa signature, le compilateur peut déduire le type d'entrée à partir du contexte. Les crochets autour des entrées ont également disparu. Cela n'est possible que parce qu' il s'agit d'un seul paramètre. Si vous en avez deux ou plus, les crochets sont obligatoires. Il y a encore une chose que nous pouvons maintenant déduire. Cela a trait au corps et à la déclaration de retour. Dans le cas d' une seule ligne de code dans le corps de la méthode, le compilateur peut en déduire que cette ligne de code est en fait l' instruction de retour du corps. Avec cette dernière étape, nous avons atteint l'expression lambda complète. Vous verrez tout le temps lorsque vous travaillez avec des chaînes. En fait, il existe un moyen d' écrire le lambda encore plus court. Dans certains cas. C'est ce qu'on appelle la référence de méthode Mais je suggère de le rechercher vous-même lorsque vous aurez une bonne compréhension des longues doses en général. Une dernière chose importante à mentionner à propos de lumped us est que les variables locales qui y sont utilisées doivent être finales ou effectivement finales. fait, final signifie une variable qui ne possède pas le mot clé final, mais dont la valeur ne change pas après sa première attribution. La raison en est que nous sommes regroupés en gros un morceau de code que vous pouvez exécuter avec d'autres méthodes. Comme la façon dont vous pouvez transmettre notre prédicat à une opération de filtre au sein d'une chaîne. Pour cette raison, Java doit créer une copie de la variable locale à utiliser dans les poumons. Pour éviter les problèmes de simultanéité. L'alpha a décidé de restreindre complètement les variables locales. Résumons ce que nous avons appris jusqu'à présent. Les classes internes anonymes sont des classes internes qui implémentent une interface sans nom, et qui doivent être déclarées et instanciées une seule fois. Les interfaces fonctionnelles sont des interfaces régulières , sauf que les seules contiennent une seule méthode qui doit être mise en œuvre. L'annotation de l'interface fonctionnelle qui peut être utilisée pour appliquer cette règle n'est pas nécessaire. Nous sommes regroupés en classes internes anonymes d' interfaces fonctionnelles dont le compilateur Java peut déduire informations manquantes en fonction du contexte. Nous savons maintenant comment créer une expression lambda et une classe interne anonyme irrégulière. Enfin, les variables locales utilisées dans lumped us doivent être finales ou effectivement correctes. 4. Opérations de diffusion: Dans les chapitres suivants, j'expliquerai les opérations couramment utilisées sur les chaînes. Mais d'abord, nous devons parler des deux types d'opérations possibles, les opérations intermédiaires et les opérations terminales. Un flux n'est complètement exécuté que lorsqu'une opération sur un terminal est utilisée. Par conséquent, un flux se termine toujours par une opération de terminal et ne peut avoir qu'un seul d' entre eux dans un flux. Les opérations intermédiaires sont toutes les opérations effectuées avant l'opération finale du terminal. Les opérations intermédiaires renvoient une instance de flux, ce qui permet de les enchaîner toutes. Comme toutes les opérations intermédiaires renvoient un flux, vous pouvez stocker une chaîne sans opérations de terminal dans une variable. Merci aujourd'hui, vous pouvez donc ajouter des étapes à votre flux en fonction d'influences externes, comme un filtre différent ou une manière différente d' enrichir les données. Attention, même si vous pouvez stocker des opérations intermédiaires dans des variables, il n'est pas possible d'exécuter le même flux deux fois avec une opération sur un terminal. Le compilateur ne le reconnaît pas, mais vous obtiendrez une exception comme celle-ci lors de l'exécution. Encore une fois. Les opérations intermédiaires renvoient un flux et peuvent donc être liées et stockées dans des variables. Les opérations intermédiaires seules n'exécutent pas un flux. Une opération de terminal exécute le flux complet et renvoie une valeur autre qu'un flux. Un flux ne peut être exécuté qu'une seule fois avec une opération sur un terminal. vous essayez de le faire deux fois , une exception se produit lors de l'exécution. Forts de ces connaissances, nous passerons aux opérations couramment utilisées. 5. Exploitation intermédiaire : filtre: Commençons par les bases. Filtre. Le filtre est une opération intermédiaire qui permet filtrer les objets des chaînes qui ne passent pas le test donné. Vous pouvez voir le filtre d'opération intermédiaire comme l'équivalent en flux d'une instruction if. entrée est un prédicat qui, comme nous l'avons appris, reçoit un objet, effectue un test dessus, renvoie vrai ou faux selon qu'il a réussi le test ou non. Voici un exemple de son utilisation. Et ne vous inquiétez pas pour les autres opérations. Nous y reviendrons bientôt. Dans cet exemple, nous utilisons un filtre pour continuer le flux uniquement avec les objets dont la liste de numéros de téléphone est vide. Avant de revenir aux clients restants sous forme de liste, filtrage peut être effectué en utilisant n'importe quelle valeur finale efficace. Ici, nous filtrons en fonction de notre variable locale, par exemple, nous pouvons également les enchaîner en utilisant plusieurs filtres d'affilée. L'opération de filtrage est un excellent exemple de la manière dont les flux rendent votre code plus lisible. Surtout si vous avez stocké longtemps dans une valeur comme celle-ci. Vous pouvez désormais voir en un coup d'œil ce que nous filtrons. 6. Exploitation du terminal : pour chaque: Notre première opération de terminal pour chacun d'entre eux. Le ForEach est une opération de terminal très simple. Il est utilisé pour effectuer une certaine action sur tous les éléments du flux. En supposant que les éléments du processus, ses intrants, sont des consommateurs. Il prend donc un objet, en fait quelque chose, mais ne renvoie aucune valeur. Ensuite. Nous avons vu sa mise en œuvre dans l'opération évoquée précédemment, mais la voici une fois de plus. Dans cet exemple, nous imprimons le prénom de chaque secteur d'activité client. Gardez à l'esprit que pour chacun d'entre eux, n'opérez sur les éléments qu'une fois qu'ils ont parcouru le reste du flux. Donc, si nous plaçons un filtre avant le fonctionnement du terminal , seuls les clients possédant moins de trois appareils obtiennent leur prénom et l'impriment. Enfin, savait-elle qu' une méthode normale peut également être utilisée de manière groupée ? Prenez cette méthode, par exemple cela ne ressemble-t-il pas à une implémentation destinée aux consommateurs, selon vous ? Il accepte un seul objet, fait quelque chose, mais ne renvoie aucune valeur par la suite. Et en effet, nous pouvons utiliser cette méthode dans notre ForEach, rendre plus lisible au cours du processus. Et c'est tout. Pour chacun, il suffit d'effectuer une action spécifiée pour chaque élément du flux qui traverse le reste du flux. 7. Exploitation intermédiaire : carte: Une autre opération intermédiaire de base, la carte. La carte est une opération intermédiaire couramment utilisée pour mapper un type d'objet à un autre. Mais il est généralement également utilisé pour exécuter une logique métier. Ses entrées sont une fonction qui, comme nous le savons maintenant, prend un objet de la classe a, fait quelque chose et renvoie un objet de classe b où les clauses a et B peuvent être de la même classe. Voici un exemple de mappage de la classe a à la classe B. Ici, nous avons un objet client en entrée. Nous l'associons à une chaîne composée de son prénom et de son nom de famille avant de l'imprimer. Dans ce cas, nous mappons de la classe a à la classe B, du client à la chaîne. Dans l'exemple suivant, nous avons un objet client en tant qu' entrée sur son appareil mobile au travail. Renvoyez ensuite le même objet client, enrichissant ainsi efficacement votre objet lui-même. Dans ce cas, nous cartographions d'un client à l' autre et atteignons l' objet en cours de route. Notez que puisque le corps Lambda contient deux instructions, j'ai dû ajouter les crochets et renvoyer le mot clé. Enfin, comme pour toute opération intermédiaire, il est possible d'avoir plusieurs opérations mathématiques dans le même flux. 8. Opérations intermédiaires : flatMap: Ensuite, FlatMap. Comme son nom l'indique, FlatMap est similaire à la carte. Il s'agit d'une opération intermédiaire couramment utilisée pour mapper un type d'objet à un autre. À la différence près que FlatMap fonctionne sur des relations un-à-plusieurs. Son entrée est également une fonction, mais une restriction est imposée à l'objet renvoyé. Un flux doit être renvoyé. Nous voyons ici la signature de la méthode map et FlatMap côte à côte pour vous montrer la différence. Alors que les deux attendent la fonction, FlatMap s'attend à ce que la valeur r soit de type chaîne. Voyons ce qu'il fait et en quoi il diffère de cela. Dans nos exemples, nous avons utilisé l'objet client, qui contient une liste d'appareils. Que se passerait-il selon vous si nous utilisions l'opération cartographique pour convertir chaque client à ses appareils ? Comme vous pouvez le voir dans la sortie, mappage d'un client vers une liste d'appareils donne lieu à un flux de listes d'appareils. Une fois imprimées, ces listes sont imprimées une par une. C'est peut-être quelque chose dont vous avez besoin pour votre cas d'utilisation fonctionnel. Mais le plus souvent, vous vous intéressez à tous les appareils plutôt qu'à des listes distinctes d'appareils. C'est là qu'intervient FlatMap. Comme je l'ai déjà dit. Flatmap impose une restriction sur l'objet de retour de la fonction. Vous pouvez voir que le lambda a légèrement changé pour FlatMap et renvoie maintenant le périphérique sous forme de flux. Au lieu d'une liste. Notez dans les sorties que les appareils sont désormais imprimés un par un au lieu de liste par liste. La clé ici est que FlatMap attend des flux sous forme résultats qui sont ensuite nouveau aplatis en un seul flux. Une fois de plus ensemble. Vous pouvez désormais voir clairement la différence entre l'opération map et FlatMap. En résumé, les cartes doivent être utilisées lors de la conversion d'objets avec une relation biunivoque. Alors que FlatMap doit être utilisé lors conversion d'objets avec une relation un-à-plusieurs. Lorsque vous utilisez FlatMap, la valeur de retour est un flux d'objets. 9. Opérations intermédiaires : séquentiel et parallèle: Deux opérations sur la même pièce, séquentielles et parallèles. séquentielles et parallèles sont toutes deux des opérations intermédiaires qui rendent le flux complet séquentiel ou parallèle respectivement. Comme il s'agit d'opérations intermédiaires, elles peuvent être ajoutées simultanément au flux , même plusieurs fois. Peu importe où se situe l' opération dans le flux. L'ensemble du flux est séquentiel ou parallèle. Pas un peu des deux. Gardez à l'esprit que la dernière opération séquentielle ou parallèle mentionnait l'industrie, celle qui est réellement utilisée. Cela signifie que ce flux est exactement le même que celui-ci. Un flux est séquentiel par défaut, ce qui signifie que les éléments sont exécutés dans l'ordre dans lequel ils apparaissent dans la collection américaine. Cela signifie également que ces flux ont la même sortie. Comme tu peux le voir. en résulte une impression de un à dix dans l'ordre avec ou sans l'opération séquentielle. , lorsque nous changeons cela en parallèle, Cependant, lorsque nous changeons cela en parallèle, comme vous pouvez le constater, nous obtenons un résultat différent à chaque fois que nous exécutons le Stream. Stream est exécuté en mode multithread, ce qui signifie que le travail effectué est réparti entre différentes exécutions. Les prétendues menaces. Gardez à l'esprit que le fait de faire fonctionner un flux en parallèle ne signifie pas automatiquement que le flux peut être exécuté en toute sécurité. En tant que développeur, vous devez vous assurer que votre code fonctionne exactement de la même manière, 1236 ou quelles que soient les menaces. Comme il ne veut pas. Une autre chose à garder à l'esprit lorsque vous exécutez des tâches en parallèle est que cela ne signifie pas nécessairement que le travail est effectué plus rapidement. créer quelque chose de multithread vous devez diviser le travail en plusieurs parties, créer une exécution pour chaque partie. Travail délégué, regroupez les différents résultats en un seul. Cela entraîne une surcharge lors l' exécution du code ou du flux, dans notre cas, ce qui ne sera bénéfique si vous avez suffisamment d'éléments dans votre flux ou si votre flux est très gourmand en calcul. En résumé, les opérations séquentielles et parallèles vous permettent de rendre rapidement l'ensemble du flux séquentiel ou parallèle. exécutant un flux en parallèle, vous devez, en tant que développeur, vous assurer que le code est sécurisé par thread. 10. Exploitation intermédiaire : un aperçu: Passons à une question simple avant passer aux plus complexes. Pq. Pq est une opération intermédiaire qui vous permet littéralement de jeter un coup d'œil dans les coulisses lors de l' exécution d'une chaîne. Son utilisation principale est le débogage et l'enregistrement de ses entrées. En tant que consommateur, cela signifie qu'il reçoit une valeur et en fait quelque chose sans qu'il y ait de valeur de retour. Bien qu'il soit possible de modifier les données pendant les périodes de pointe, vous prenez le risque de le faire. En fonction de votre version de Java et du fait que le fonctionnement de votre terminal nécessite ou non fait que le fonctionnement de votre terminal de traiter les objets de la chaîne. Le code contenu dans Peek peut être exécuté ou non. Soyez très prudent lorsque vous utilisez Peak à des fins autres que le débogage et la journalisation. Voici un exemple de son utilisation. Dans cet exemple, nous utilisons peak pour imprimer le nom d' un appareil avant de continuer mapper aux détails de sa commande, collecter les éventuels traitements ultérieurs. L'un des résultats de ce flux est une liste des détails des commandes. Grâce au pic de fonctionnement, nous pouvons obtenir une certaine journalisation avec un appareil que les objets utilisent pour les résultats. Et j'ai vu que le pic est simplement un moyen de faire de l'exploitation pendant un ruisseau. Vous pouvez l'utiliser pour modifier des données, mais c'est risqué Je vous le déconseille donc si vous n'êtes pas encore familiarisé avec les streams. 11. Exploitation du terminal : collecte: Notre deuxième opération de terminal, Collect. Collect est une opération de terminal qui collecte tous les éléments d' un flux dans quelque chose. Il est couramment utilisé pour placer les éléments résultants d' un flux dans une liste. Il existe deux implémentations pour celle-ci. La première prévoit une implémentation de l'interface du collecteur. Cependant, il ne s'agit pas d'une interface fonctionnelle et ne peut donc pas être réécrite en tant qu'expression lambda. Heureusement pour nous, oui, Lava a eu la gentillesse de fournir aux collectionneurs des clusters contenant toutes sortes de méthodes utiles. Nombre d'entre elles dépassent le cadre de cet atelier. Mais il y en a une que vous utiliserez fréquemment pour les collectionneurs et deux listes. Comme on pouvait s'y attendre. Cela renvoie une implémentation de l'interface du collecteur qui collecte tous les éléments de la chaîne dans une liste et la renvoie. Personnellement, je l'utilise 190, 9 % des fois où j'ai besoin de collecter quelque chose et je m'attends à ce que vous viviez la même chose. Mais pour comprendre un peu mieux ce qu'il fait, passons en revue la deuxième implémentation. Celui-ci attend un fournisseur et deux des consommateurs. Le document Java nous donne un bon aperçu de ce qu'il fait. Le fournisseur nous fournit ce que nous attendons de l'opération de collecte. Ensuite, le premier consommateur de vélo est habitué à consommer un élément du flux pour obtenir ces résultats. Cela se poursuit jusqu'à ce que tous les éléments du flux ou soient consommés dans les résultats finaux. Cela ne nous montre pas ce que fait le deuxième consommateur bi à le combiner, mais c' est parce que le combineur n' est nécessaire que lorsque le flux est diffusé en parallèle. Dans ce cas, vous pouvez avoir deux fils de discussion ou plus en commençant par le fournisseur. Une fois toutes les menaces éliminées, les résultats de ces threads doivent être combinés en un seul résultat, exactement à quoi sert un combineur. Mettons-le en pratique. En utilisant un fournisseur et deux par les consommateurs. Je vais répliquer la collecte des éléments clients dans un flux. Nous allons commencer par le fournisseur. Quand les appels obtiendront la liste vide dans laquelle nous mettrons tous les éléments du flux. Ensuite, nous avons besoin d'un consommateur de vélo qui accumule tous les éléments de la chaîne dans la liste des fournitures. Cela montre clairement que notre résultat est bien cette liste et que chaque élément client du stream est accumulé dans une liste définie. Dans le cas d'un flux séquentiel, ce sera la fin de celui-ci. Mais pour permettre un traitement parallèle, il faudra une version finale par le consommateur qui combine deux résultats en un seul. En utilisant cela par le consommateur, nous ajoutons les éléments du deuxième résultat au premier. Cette opération est répétée par le flux jusqu'à ce que tous les résultats des menaces soient fusionnés en un seul. Ici, ils sont renseignés dans l'opération de collecte. Et grâce à cela, vous savez comment créer vos propres collections sur mesure. Je le répète, il existe deux implémentations de la coopération de collecte. La première attend un collecteur pour lequel Java a préparé des options pour vous à l'aide de la clause collectors. Le second attend un fournisseur et lie les consommateurs, ce qui le rend beaucoup plus personnalisable. Vous utiliserez la collection préparée de cette classe la plupart du temps. Mais au moins maintenant tu sais comment ça fonctionne. 12. Exploitation du terminal : réduire: Le dernier opérateur discutera de la réduction. Reduce est une opération de terminal qui peut être utilisée pour réduire tous les éléments d'un flux en un seul objet. C'est un peu comme une opération de collecte dont nous avons parlé. Mais tandis que collect applique tous les éléments du flux à un conteneur immuable comme une liste ou un ensemble. Reduce ne collecte pas mais applique tous les éléments à un seul objet. L'identité. Réduisez, prend son identité, accumule des éléments dans l'identité, puis combine plusieurs résultats en un seul au cas où tout serait exécuté en parallèle. Réduire est l' opération la plus difficile à appréhender. Alors ne vous sentez pas mal si vous ne recevez pas tout cela en même temps. Prenez simplement votre temps pour suivre cette section et essayez les exercices à la fin du cours. S'il vous reste des questions, hésitez pas à les poser via la plateforme. Très bien, plongeons-nous. Deep Reduce attend une valeur de départ appelée fonction d'identité qui est utilisée pour cumuler et un opérateur binaire utilisé pour combiner les résultats issus de threads distincts. Le chien alpha nous donne un bel aperçu de ce qu'il fait. Cette identité nous donne le point de départ des résultats. Il doit s'agir d'une feuille blanche et vide, telle sorte que l'ajout de la valeur du flux à cette identité ait ce résultat et soit modifié en tant que produit. Ensuite, pour chaque élément du flux, il est accumulé dans la valeur résultante à l'aide de la fonction by. Tout comme pour collecter, cela ne nous montre pas ce que fait l'opérateur binaire, le combineur. Il en va de même ici. Le combineur est uniquement utilisé pour combiner les résultats de plusieurs threads dans le cas où le flux est exécuté en parallèle. Mettons-le en pratique. Pour notre exemple, nous allons, nous allons sélectionner tous les clients dans un entier représentant le nombre total d' appareils détenus par ces clients ensemble. Notre identité doit être un entier. Par conséquent, nous voulons sortir de cette tendance. En ce qui concerne la valeur. N'oubliez pas que l'ajout d'un résultat à l'identité doit entraîner une modification en tant que produit. Dans notre cas, nous devrons additionner la taille de toutes les listes d'appareils pour obtenir nos résultats finaux. Quelle valeur de l' identité signifie que identité plus la taille de la liste des appareils est égale à deux. L'appareil, c'est vrai, zéro. Notre identité sera donc la suivante. Ensuite, nous avons besoin d'une fonction qui produit un élément du flux dans cette identité. Le premier générique utilisé dans la fonction by est un entier qui représente la valeur actuelle des résultats. Le sous-total, si vous voulez. La deuxième utilisation des génériques est l'élément du flux, qui sera réduit au sous-total. La troisième utilisation générique est le type du résultat de l' opération, un entier. Ce troisième terme générique doit être identique au premier, ce qui est logique puisque le premier terme générique représente le sous-total. Dans le cas d'un flux séquentiel, ce serait la fin de celui-ci. Mais pour permettre un traitement parallèle, il faudra un opérateur binaire pour combiner deux résultats en un seul. À l'aide de cet opérateur binaire, nous combinons les résultats de deux threads. Ceci est répété par le flux jusqu'à ce que tous les résultats des threads soient fusionnés en un seul. Ici, ils sont intégrés à l'opération de réduction. Je le répète, nous partons d'une table rase vide en tant qu'identité zéro. Dans notre cas. Nous ajoutons ensuite la taille de la liste des appareils de chaque élément du flux à cette identité. Si le flux est exécuté en parallèle, nous les combinons pour ajouter deux sous-totaux en un seul jusqu'à ce qu'il ne nous reste qu' un seul résultat. Dans notre exemple, nous avons réduit nos objets complexes en un seul entier. Mais la réduction peut également être utilisée pour réduire tous les éléments d'un flux en un seul objet complexe. Par exemple, nous pourrions réduire nos clients à un seul client contenant nos informations. Mais je vais laisser celui-ci dans le cadre des exercices que vous pouvez faire vous-même. 13. Résumé et mot après-vente: Nous sommes arrivés à la fin de ce cours. Résumons pour voir ce que nous avons appris au notre transition vers l'API Java eight Streams. Nous avons commencé par apprendre à quoi servent les flux et comment ils fonctionnent. Nous avons ensuite expliqué comment créer une expression lambda à partir d' une classe interne anonyme grâce à des interfaces fonctionnelles. Nous avons brièvement discuté, mais les interfaces fonctionnelles le sont, et de celles que vous utilisez couramment lorsque vous travaillez avec des flux. Enfin, nous avons passé en revue les opérations intermédiaires et terminales couramment utilisées. Merci d'avoir regardé ce cours. J'espère que vous en avez suffisamment appris sur les streams pour reconnaître les situations dans lesquelles vous pouvez et êtes capable de les utiliser. Si vous souhaitez m'aider à améliorer ce cours et nous dire si vous l' avez trouvé utile ou non. Je vous serais reconnaissant de laisser un commentaire. Comme promis. Je vous ai préparé quelques exercices pour voir si vous pouvez appliquer les connaissances apprises au cours de ce cours. Chaque exercice comporte une demande, un résultat attendu pour que vous puissiez vérifier si vous l'avez bien fait. S'il y a quelque chose de flou sur ce cours, des exercices déjà fournis, n'hésitez pas à m'envoyer un message avec vos questions. Je vais vous aider de mon mieux. Encore une fois. Merci de votre attention et jusqu'à la prochaine fois.