Maintenant, jetons un coup d'œil à Java Stream. Fondamentalement, il est résumé en faisant référence à JavaDoc of Stream, mais la méthode Étant donné que des détails tels que la variable de type de l'argument interne sont omis, reportez-vous à JavaDoc pour plus de détails. Stream est un concept apparu dans Java 8 et peut effectuer divers traitements sur une collection d'éléments.
Les opérations de flux peuvent être divisées en trois étapes: générer, intermédiaire et terminer. Les opérations de génération et d'arrêt ne peuvent être effectuées qu'une seule fois par opération de flux, mais les opérations intermédiaires peuvent être effectuées plusieurs fois. Étant donné que la méthode d'opération intermédiaire est conçue comme une méthode qui renvoie une instance Stream, elle peut être décrite par une chaîne de méthodes.
Variable de résultat=produire().Fonctionnement intermédiaire 1().Fonctionnement intermédiaire 2().Fonctionnement intermédiaire 3().Opération de terminaison();
Comme son nom l'indique, la création est le processus de création d'un flux en premier.
Cependant, Stream est une interface et les classes d'implémentation ne sont pas fournies sous la forme instanciée habituelle.
La Collection fournit les méthodes stream ()
et parallel ()
, qui vous permettent d'obtenir le Stream d'un élément, mais dans de nombreux cas, vous voulez simplement obtenir le Stream sans créer de Collection.
Par conséquent, vous pouvez créer un Stream à l'aide des méthodes statiques suivantes fournies par Stream.
Méthode | Contenu | Nombre d'éléments |
---|---|---|
empty() | [] | Limité(Ciel) |
of(Object e1, Object e2, Object e3, …) | [e1, e2, e3, …] | Limité(Identique à l'argument) |
iterate(T s,Function f) | [s, f(s), f(f(s)), f(f(f(s))))…} | infini |
generate(Function f) | [f(),f(),f(),f()…] | infini |
concat(Stream s1, Stream s2) | [Tous les éléments de s1,Tous les éléments de s2] | Par argument |
Type d'élément dans T: Stream
Vous pouvez également utiliser le Builder obtenu à partir de Stream.builder ()
pour générer un Stream.
Builder<Integer> builder = Stream.builder();
IntStream s = Stream.builder().add(1).add(2).add(3).build();
Les flux infinis générés par ʻiterateou
generate` doivent être interrompus en utilisant la limite de l'opération intermédiaire décrite ci-dessous (sinon vous vous retrouverez dans une boucle infinie).
Les opérations intermédiaires opèrent sur les éléments du Stream. L'opération intermédiaire renvoie une nouvelle instance Stream après avoir appliqué l'opération à chaque élément, afin que vous puissiez concaténer les opérations intermédiaires dans la chaîne de méthodes. Les opérations intermédiaires sont grossièrement divisées en opérations de changement de caractéristiques, opérations sans état et opérations avec état.
L'opération de changement de propriété est une opération qui modifie les propriétés du flux lui-même. Les éléments du contenu ne changent pas. Il est défini dans son interface parente, BaseStream, pas Stream.
Méthode | Contenu |
---|---|
parallel() | Flux parallèle |
sequential() | Flux séquentiel |
unordered() | Flux non ordonné |
onClose(Runnable r) | Enregistrement d'un gestionnaire à la fermeture |
Les opérations intermédiaires sans état sont des opérations intermédiaires qui ne sont pas affectées par d'autres éléments lorsqu'elles fonctionnent sur un élément. Par conséquent, il convient au traitement parallèle et il est recommandé que le traitement intermédiaire soit aussi apatride que possible. Ci-après, e et en (n: entier) sont les éléments du flux.
Méthode | Contenu |
---|---|
filter(Predicate p) | p(e)Si est faux, supprimez l'élément e |
map(Function f) | [f(e1),f(e2),f(e3),…] |
flatMap(Function f) | [f(e1)Tous les éléments du flux renvoyés par, f(e2)Tous les éléments du flux renvoyés par,f(e3)Tous les éléments du flux renvoyés par,…] |
peek(Function f) | Exécutez f pour chaque élément, en laissant les éléments du flux tels quels |
Les opérations intermédiaires avec état sont des opérations intermédiaires qui sont affectées par d'autres éléments lorsque vous opérez sur un élément.
Certaines opérations peuvent nécessiter tous les éléments du Stream pour renvoyer le résultat.
Par exemple, la méthode sorted
qui réalise le traitement de tri est un exemple.
En raison de l'influence d'autres facteurs, les opérations intermédiaires avec état nécessitent le contrôle du traitement complexe pendant le traitement parallèle, ce qui peut être moins efficace que le traitement séquentiel.
Méthode | Contenu |
---|---|
distinct() | Supprimer les éléments en double dans le flux |
sorted() | Tri dans l'ordre naturel pour les classes d'implémentation comparables |
sorted(Comparator c) | Tri à l'aide du comparateur |
limit(long maxSize) | Tronquer jusqu'à la longueur d'éléments maxSize |
skip(long n) | Supprimer les n premiers éléments |
«limite» est surtout appelée opération intermédiaire de court-circuit. Les opérations de court-circuit sont des opérations qui ont le potentiel de transformer un flux infini en un flux fini.
Il est facile de penser que «limit» et «skip» sont plus rapides en traitement parallèle que «distinct» et «sorted» car ils ne regardent que le nombre d'éléments, mais dans un flux ordonné, «n depuis le début». C'est une opération coûteuse car il faut le savoir. Si vous souhaitez donner la priorité à l'exécution parallèle et que vous n'avez pas besoin de maintenir l'ordre, vous pouvez vous attendre à une amélioration de l'efficacité en ne commandant pas avec ʻunordered`.
L'opération de terminaison traite le contenu du Stream au moment où il est appelé et renvoie un résultat autre que le Stream (y compris aucun résultat (void)). Une fois l'opération d'arrêt terminée, le Stream qui a été utilisé jusque-là devient inutilisable, et si vous essayez de l'utiliser à nouveau, une IllegalStateException sera levée. Par conséquent, il est correct de gérer les objets Stream dans la chaîne de méthodes plutôt que dans des variables.
Méthode | Type de retour | Contenu |
---|---|---|
close() | void | Fermez le flux. Tous les gestionnaires de fermeture enregistrés avec onClose sont appelés |
iterator() | Iterator | Renvoie un itérateur |
spliterator() | Spliterator | Renvoie le séparateur |
forEach(Consumer action) | void | Exécutez une action pour chaque élément. Ne pas garantir la commande |
forEachOrdered(Consumer action) | void | Identique à forEach, mais garantit l'ordre |
toArray() | Object[] | Organiser |
reduce(T unit, BinaryOperator acc) | T | réduction(Plier).. Renvoie le résultat de la combinaison d'éléments avec la fonction cumulative acc pour l'unité d'élément unitaire. |
collect(Supplier factory, BiConsumer acc, BiConsumer combiner) | Conteneur de résultats | Réduction variable. Conteneur variable généré par l'usine(Par exemple ArrayList)D'autre part, ajoutez un élément avec acc et combinez chaque récipient avec le combineur. |
min() | Optional | Renvoie le plus petit élément. Cas particulier de réduction |
max() | Optional | Renvoie le plus grand élément. Cas particulier de réduction |
count() | long | Renvoie le nombre d'éléments. Cas particulier de réduction |
anyMatch(Predicate p) | boolean | p(e)Renvoie vrai si même l'un des résultats de l'évaluation est vrai |
allMatch(Predicate p) | boolean | p(e)Renvoie vrai si tous les résultats d'évaluation de |
noneMatch(Predicate p) | boolean | p(e)Renvoie vrai si tous les résultats d'évaluation sont faux |
findFirst() | Optional | Renvoie le premier élément. Renvoie des éléments arbitraires pour les flux non ordonnés |
findAny() | Optional | Renvoie n'importe quel élément |
Type d'élément dans T: Stream
Est-il difficile de comprendre les opérations de réduction telles que «réduire» et «collecter»? J'écrirai plus à ce sujet dans un autre article dans un proche avenir. → Écrit. En outre, le nom inconnu Splitterator est sorti. Un séparateur est un itérateur qui peut être traité en parallèle (divisible). Le séparateur est géré dans le flux et le traitement est effectué pour chaque séparateur divisé pendant le traitement parallèle.
Recommended Posts