Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre Traitement des Éléments avec la Méthode forEach() | Opérations Terminales dans l'API Stream
API Stream

bookTraitement des Éléments avec la Méthode forEach()

Vous connaissez déjà la méthode forEach() puisque vous l'avez utilisée en pratique pour afficher chaque élément d'une collection sur la console. Examinons-la de plus près et explorons ses implémentations.

Elle offre un moyen pratique de traiter les données selon un style fonctionnel. Cependant, il est important de noter que l'ordre de traitement dépend du type de flux et de la méthode utilisée.

Il existe deux implémentations de la méthode forEach() dans la Stream API. Examinons-les une par une.

Méthode forEach

Exécute une action sur chaque élément, mais l'ordre de traitement n'est pas garanti dans les flux parallèles.

void forEach(Consumer<? super T> action)

La méthode forEach() prend un Consumer<T> en argument—une interface fonctionnelle qui définit une opération pour chaque élément du flux. Elle est couramment utilisée pour la journalisation, l'affichage ou l'exécution d'effets de bord.

Exemple pratique

Dans une boutique en ligne, les utilisateurs doivent recevoir des notifications concernant des remises personnalisées. Comme l'ordre n'a pas d'importance, forEach() est utilisé avec un flux parallèle pour une exécution plus rapide.

Main.java

Main.java

copy
1234567891011121314151617181920212223
package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { List<String> customers = List.of( "alice@example.com", "bob@example.com", "charlie@example.com" ); // Parallel stream for faster processing Stream<String> customerStream = customers.parallelStream(); customerStream.forEach(email -> sendDiscountEmail(email)); } private static void sendDiscountEmail(String email) { System.out.println("Sending discount email to: " + email); // Simulating email sending process } }

Ce code simule l'envoi de courriels de réduction personnalisés aux clients. Comme parallelStream() est utilisé, les courriels sont envoyés dans un ordre aléatoire pour améliorer la rapidité. La méthode forEach() applique l'action donnée à chaque courriel.

Méthode forEachOrdered

Exécute une action tout en préservant l'ordre des éléments, même dans les flux parallèles.

void forEachOrdered(Consumer<? super T> action)

Comme forEach, cette méthode accepte également un Consumer<T>, mais elle garantit que les éléments sont traités dans le même ordre que celui du flux d'origine. Ceci est utile lorsque le maintien de la séquence est essentiel.

Exemple pratique

Considérer un système de paiement où chaque transaction doit être traitée dans l'ordre exact de son arrivée. Si les paiements sont traités dans un ordre différent, cela peut entraîner des erreurs, telles que des calculs de solde incorrects.

Main.java

Main.java

copy
123456789101112131415161718192021
package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { List<String> payments = List.of( "Payment #5001 - $100", "Payment #5002 - $250", "Payment #5003 - $75" ); Stream<String> paymentStream = payments.parallelStream(); paymentStream.forEachOrdered(payment -> processPayment(payment)); } private static void processPayment(String payment) { System.out.println("Processing payment: " + payment); } }

Ce code simule un système de traitement des paiements où les transactions doivent être traitées dans l'ordre d'arrivée. L'utilisation de parallelStream() améliore les performances, mais forEachOrdered() garantit que la séquence reste intacte.

Comparaison des performances : forEach() vs. forEachOrdered()

Évaluation de la rapidité d'exécution de forEach() par rapport à forEachOrdered() lors de l'utilisation de flux parallèles. Pour cela, création d'une liste de 10 millions d'éléments, traitement avec les deux méthodes en calculant la racine carrée de chaque nombre, puis enregistrement du temps d'exécution.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031
package com.example; import java.util.List; import java.util.stream.IntStream; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); IntStream.range(0, 10_000_000).forEach(numbers::add); // Create a list with 10 million elements // Measure execution time of `forEach()` long startTime = System.nanoTime(); numbers.parallelStream().forEach(num -> process(num)); long forEachTime = System.nanoTime() - startTime; // Measure execution time of `forEachOrdered()` startTime = System.nanoTime(); numbers.parallelStream().forEachOrdered(num -> process(num)); long forEachOrderedTime = System.nanoTime() - startTime; // Print results System.out.println("forEach execution time: " + forEachTime / 1_000_000 + " ms"); System.out.println("forEachOrdered execution time: " + forEachOrderedTime / 1_000_000 + " ms"); } private static void process(int num) { // Simulate workload Math.sqrt(num); } }

La méthode forEach() traite les éléments sans préserver l'ordre, permettant au flux de répartir librement les tâches entre les cœurs de processeur disponibles. Cela maximise les performances, car chaque thread peut sélectionner les éléments dans n'importe quel ordre et les traiter en parallèle sans restrictions.

La méthode forEachOrdered() préserve l'ordre d'origine des éléments, ce qui nécessite une synchronisation supplémentaire. Dans un flux parallèle, les éléments sont d'abord divisés en blocs pour le traitement, mais leurs résultats doivent ensuite être réassemblés dans le bon ordre avant d'être transmis à la méthode de traitement.

1. Quelle interface fonctionnelle la méthode forEach accepte-t-elle ?

2. Quelle sortie ce code peut-il produire ?

question mark

Quelle interface fonctionnelle la méthode forEach accepte-t-elle ?

Select the correct answer

question mark

Quelle sortie ce code peut-il produire ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 3. Chapitre 4

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

Awesome!

Completion rate improved to 2.33

bookTraitement des Éléments avec la Méthode forEach()

Glissez pour afficher le menu

Vous connaissez déjà la méthode forEach() puisque vous l'avez utilisée en pratique pour afficher chaque élément d'une collection sur la console. Examinons-la de plus près et explorons ses implémentations.

Elle offre un moyen pratique de traiter les données selon un style fonctionnel. Cependant, il est important de noter que l'ordre de traitement dépend du type de flux et de la méthode utilisée.

Il existe deux implémentations de la méthode forEach() dans la Stream API. Examinons-les une par une.

Méthode forEach

Exécute une action sur chaque élément, mais l'ordre de traitement n'est pas garanti dans les flux parallèles.

void forEach(Consumer<? super T> action)

La méthode forEach() prend un Consumer<T> en argument—une interface fonctionnelle qui définit une opération pour chaque élément du flux. Elle est couramment utilisée pour la journalisation, l'affichage ou l'exécution d'effets de bord.

Exemple pratique

Dans une boutique en ligne, les utilisateurs doivent recevoir des notifications concernant des remises personnalisées. Comme l'ordre n'a pas d'importance, forEach() est utilisé avec un flux parallèle pour une exécution plus rapide.

Main.java

Main.java

copy
1234567891011121314151617181920212223
package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { List<String> customers = List.of( "alice@example.com", "bob@example.com", "charlie@example.com" ); // Parallel stream for faster processing Stream<String> customerStream = customers.parallelStream(); customerStream.forEach(email -> sendDiscountEmail(email)); } private static void sendDiscountEmail(String email) { System.out.println("Sending discount email to: " + email); // Simulating email sending process } }

Ce code simule l'envoi de courriels de réduction personnalisés aux clients. Comme parallelStream() est utilisé, les courriels sont envoyés dans un ordre aléatoire pour améliorer la rapidité. La méthode forEach() applique l'action donnée à chaque courriel.

Méthode forEachOrdered

Exécute une action tout en préservant l'ordre des éléments, même dans les flux parallèles.

void forEachOrdered(Consumer<? super T> action)

Comme forEach, cette méthode accepte également un Consumer<T>, mais elle garantit que les éléments sont traités dans le même ordre que celui du flux d'origine. Ceci est utile lorsque le maintien de la séquence est essentiel.

Exemple pratique

Considérer un système de paiement où chaque transaction doit être traitée dans l'ordre exact de son arrivée. Si les paiements sont traités dans un ordre différent, cela peut entraîner des erreurs, telles que des calculs de solde incorrects.

Main.java

Main.java

copy
123456789101112131415161718192021
package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { List<String> payments = List.of( "Payment #5001 - $100", "Payment #5002 - $250", "Payment #5003 - $75" ); Stream<String> paymentStream = payments.parallelStream(); paymentStream.forEachOrdered(payment -> processPayment(payment)); } private static void processPayment(String payment) { System.out.println("Processing payment: " + payment); } }

Ce code simule un système de traitement des paiements où les transactions doivent être traitées dans l'ordre d'arrivée. L'utilisation de parallelStream() améliore les performances, mais forEachOrdered() garantit que la séquence reste intacte.

Comparaison des performances : forEach() vs. forEachOrdered()

Évaluation de la rapidité d'exécution de forEach() par rapport à forEachOrdered() lors de l'utilisation de flux parallèles. Pour cela, création d'une liste de 10 millions d'éléments, traitement avec les deux méthodes en calculant la racine carrée de chaque nombre, puis enregistrement du temps d'exécution.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031
package com.example; import java.util.List; import java.util.stream.IntStream; import java.util.ArrayList; public class Main { public static void main(String[] args) { List<Integer> numbers = new ArrayList<>(); IntStream.range(0, 10_000_000).forEach(numbers::add); // Create a list with 10 million elements // Measure execution time of `forEach()` long startTime = System.nanoTime(); numbers.parallelStream().forEach(num -> process(num)); long forEachTime = System.nanoTime() - startTime; // Measure execution time of `forEachOrdered()` startTime = System.nanoTime(); numbers.parallelStream().forEachOrdered(num -> process(num)); long forEachOrderedTime = System.nanoTime() - startTime; // Print results System.out.println("forEach execution time: " + forEachTime / 1_000_000 + " ms"); System.out.println("forEachOrdered execution time: " + forEachOrderedTime / 1_000_000 + " ms"); } private static void process(int num) { // Simulate workload Math.sqrt(num); } }

La méthode forEach() traite les éléments sans préserver l'ordre, permettant au flux de répartir librement les tâches entre les cœurs de processeur disponibles. Cela maximise les performances, car chaque thread peut sélectionner les éléments dans n'importe quel ordre et les traiter en parallèle sans restrictions.

La méthode forEachOrdered() préserve l'ordre d'origine des éléments, ce qui nécessite une synchronisation supplémentaire. Dans un flux parallèle, les éléments sont d'abord divisés en blocs pour le traitement, mais leurs résultats doivent ensuite être réassemblés dans le bon ordre avant d'être transmis à la méthode de traitement.

1. Quelle interface fonctionnelle la méthode forEach accepte-t-elle ?

2. Quelle sortie ce code peut-il produire ?

question mark

Quelle interface fonctionnelle la méthode forEach accepte-t-elle ?

Select the correct answer

question mark

Quelle sortie ce code peut-il produire ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 3. Chapitre 4
some-alt