[JAVA] Comportement détaillé de l'opération intermédiaire avec état de l'API Stream et de l'opération de terminaison de court-circuit

Comportement détaillé de l'opération intermédiaire avec état de l'API Stream et de l'opération d'arrêt

Le premier est le problème.

Qu'en est-il de la sortie console du code ci-dessous?


//question 1
		Stream.of(1, 2, 3, 4, 5).map(i -> {
			System.out.println(i);
			return i * 2;
		}).filter(i -> i > 3).findFirst();
//question 2
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).findFirst();
//question 3
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).sorted().findFirst();
//Question 4
		Stream.of(1, 2, 3, 4, 5).peek(System.out::println).map(i -> {
			return i * 2;
		}).filter(i -> i > 3).distinct().findFirst();

répondre

//question 1
1
2
//question 2
1
2
//question 3
1
2
3
4
5
//Question 4
1
2

Commentaire

question 1

Le traitement de flux de java est divisé en «génération», «opération intermédiaire» et «opération de terminaison». En gros, la partie où la génération crée le Stream, la méthode où l'opération de terminaison renvoie finalement le résultat, Ce n'est pas grave si vous considérez l'opération intermédiaire comme la partie qui renvoie Stream à partir d'autres Streams.

Le traitement proprement dit est exécuté lorsque l'opération d'arrêt est exécutée. Et fondamentalement, il exécute l'opération de terminaison pour chaque élément circulant dans Stream. Tous les éléments ne sont pas mappés puis filtrés. (Par exemple, le comportement est différent de l'écriture de code similaire dans un tableau javascript.)

Et, FindFirst adoptée comme opération de terminaison cette fois est appelée opération de terminaison de court-circuit parmi les opérations de terminaison. Une opération avec un "court-circuit" se terminera avant même que tous les éléments circulant dans le Stream ne soient évalués si les conditions sont remplies. (Si l'opération de court-circuit remplit les conditions, il est possible de terminer le processus sans tomber dans une boucle infinie même pour un Stream qui renvoie une valeur infinie (comme un Stream créé à partir d'un itérateur qui hasNext renvoie toujours true).)

Dans une boucle for ou while, si même une condition est remplie, elle se rompt et le reste est ignoré, mais il le fait automatiquement. C'est intelligent.

Dans ce cas, findFirst peut renvoyer la valeur lorsque 2 flux, le traitement du flux est interrompu jusqu'à 1 et 2.

question 2

C'est fondamentalement la même chose que la question 1. Si vous jetez un coup d'œil immédiatement après avoir créé un Stream avec 5 éléments qui coulent, il semble être exécuté 5 fois, Le traitement de flux s'arrête à 2 car la fin est le traitement de fin de court-circuit.

question 3

Dans certains cas, les éléments traversant tous les flux sont évalués même si une terminaison de court-circuit est effectuée. C'est le cas du "traitement intermédiaire avec état" entre les deux. Dans ce cas, trié est un processus intermédiaire avec état. Puisqu'il s'agit d'un processus de tri et d'obtention de celui qui satisfait la condition en premier Naturellement, il est nécessaire de se référer logiquement à tous les éléments.

À propos, la question de savoir si chaque processus intermédiaire est avec état est décrite dans Référence officielle. ..

Question 4

En passant, il n'est pas toujours nécessaire de faire référence à tous les éléments avec une opération intermédiaire avec état. distinct est également une opération intermédiaire avec état, mais elle est également effectuée en 1 et 2. En fait, tous les éléments sont toujours référencés dans un Stream ordonné normal uniquement lors de l'utilisation de sorted.

Résumé

De côté

Dans le cas de ParallelStream, le comportement est légèrement différent, Ce sera long, donc par ici.

Recommended Posts

Comportement détaillé de l'opération intermédiaire avec état de l'API Stream et de l'opération de terminaison de court-circuit
[Java] Opération intermédiaire de l'API Stream
[Java] Stream API - Traitement de l'arrêt du flux
[Java] Stream API - Traitement intermédiaire de flux