Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Elementen Verwerken met de forEach()-Methode | Terminale Operaties in de Stream API
Stream-API

bookElementen Verwerken met de forEach()-Methode

Je bent al bekend met de methode forEach() omdat je deze in de praktijk hebt gebruikt om elk element van een collectie naar de console te printen. Laten we deze methode nader bekijken en de implementaties ervan verkennen.

Deze methode biedt een handige manier om gegevens op een functionele wijze te verwerken. Het is echter belangrijk op te merken dat de verwerkingsvolgorde afhankelijk is van het type stream en de gebruikte methode.

Er zijn twee implementaties van de methode forEach() in de Stream API. Laten we ze één voor één doornemen.

forEach-methode

Voert een actie uit op elk element, maar de verwerkingsvolgorde is niet gegarandeerd bij parallelle streams.

void forEach(Consumer<? super T> action)

De methode forEach() accepteert een Consumer<T> als argument—een functionele interface die een bewerking definieert voor elk element in de stream. Wordt vaak gebruikt voor logging, afdrukken of het uitvoeren van neveneffecten.

Praktisch voorbeeld

In een webwinkel moeten gebruikers meldingen ontvangen over gepersonaliseerde kortingen. Omdat de volgorde niet van belang is, wordt forEach() gebruikt met een parallelle stream voor snellere uitvoering.

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 } }

Deze code simuleert het verzenden van gepersonaliseerde kortingsmails naar klanten. Omdat parallelStream() wordt gebruikt, worden e-mails in willekeurige volgorde verzonden voor verbeterde snelheid. De methode forEach() past de opgegeven actie toe op elk e-mailadres.

forEachOrdered-methode

Voert een actie uit met behoud van de volgorde van elementen, zelfs in parallelle streams.

void forEachOrdered(Consumer<? super T> action)

Net als forEach accepteert deze methode ook een Consumer<T>, maar zij garandeert dat elementen worden verwerkt in dezelfde volgorde als waarin ze in de oorspronkelijke stream voorkomen. Dit is nuttig wanneer het behouden van de volgorde essentieel is.

Praktisch voorbeeld

Stel een betalingssysteem voor waarin elke transactie exact in de volgorde van binnenkomst moet worden verwerkt. Als betalingen buiten de volgorde worden afgehandeld, kan dit leiden tot fouten, zoals onjuiste saldo-berekeningen.

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); } }

Deze code simuleert een betalingsverwerkingssysteem waarbij transacties in de volgorde van binnenkomst moeten worden afgehandeld. Het gebruik van parallelStream() verhoogt de prestaties, maar forEachOrdered() zorgt ervoor dat de volgorde behouden blijft.

Prestatievergelijking: forEach() vs. forEachOrdered()

Hier wordt gemeten hoe veel sneller forEach() wordt uitgevoerd in vergelijking met forEachOrdered() bij het werken met parallelle streams. Hiervoor wordt een lijst van 10 miljoen elementen aangemaakt, verwerkt met beide methoden door de vierkantswortel van elk getal te berekenen, en de uitvoeringstijd geregistreerd.

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); } }

De methode forEach() verwerkt elementen zonder de volgorde te behouden, waardoor de stream de taken vrij kan verdelen over de beschikbare processorkernen. Dit maximaliseert de prestaties, omdat elke thread elementen in willekeurige volgorde kan oppakken en parallel kan verwerken zonder beperkingen.

De methode forEachOrdered() behoudt de oorspronkelijke volgorde van de elementen, wat extra synchronisatie vereist. In een parallelle stream worden elementen eerst opgesplitst in delen voor verwerking, maar hun resultaten moeten vervolgens in de juiste volgorde worden samengevoegd voordat ze aan de verwerkingsmethode worden doorgegeven.

1. Welke functionele interface accepteert de methode forEach?

2. Welke uitvoer kan deze code produceren?

question mark

Welke functionele interface accepteert de methode forEach?

Select the correct answer

question mark

Welke uitvoer kan deze code produceren?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 4

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Suggested prompts:

Can you explain the main differences between forEach() and forEachOrdered()?

When should I use forEachOrdered() instead of forEach()?

Can you provide more real-world examples where order matters?

Awesome!

Completion rate improved to 2.33

bookElementen Verwerken met de forEach()-Methode

Veeg om het menu te tonen

Je bent al bekend met de methode forEach() omdat je deze in de praktijk hebt gebruikt om elk element van een collectie naar de console te printen. Laten we deze methode nader bekijken en de implementaties ervan verkennen.

Deze methode biedt een handige manier om gegevens op een functionele wijze te verwerken. Het is echter belangrijk op te merken dat de verwerkingsvolgorde afhankelijk is van het type stream en de gebruikte methode.

Er zijn twee implementaties van de methode forEach() in de Stream API. Laten we ze één voor één doornemen.

forEach-methode

Voert een actie uit op elk element, maar de verwerkingsvolgorde is niet gegarandeerd bij parallelle streams.

void forEach(Consumer<? super T> action)

De methode forEach() accepteert een Consumer<T> als argument—een functionele interface die een bewerking definieert voor elk element in de stream. Wordt vaak gebruikt voor logging, afdrukken of het uitvoeren van neveneffecten.

Praktisch voorbeeld

In een webwinkel moeten gebruikers meldingen ontvangen over gepersonaliseerde kortingen. Omdat de volgorde niet van belang is, wordt forEach() gebruikt met een parallelle stream voor snellere uitvoering.

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 } }

Deze code simuleert het verzenden van gepersonaliseerde kortingsmails naar klanten. Omdat parallelStream() wordt gebruikt, worden e-mails in willekeurige volgorde verzonden voor verbeterde snelheid. De methode forEach() past de opgegeven actie toe op elk e-mailadres.

forEachOrdered-methode

Voert een actie uit met behoud van de volgorde van elementen, zelfs in parallelle streams.

void forEachOrdered(Consumer<? super T> action)

Net als forEach accepteert deze methode ook een Consumer<T>, maar zij garandeert dat elementen worden verwerkt in dezelfde volgorde als waarin ze in de oorspronkelijke stream voorkomen. Dit is nuttig wanneer het behouden van de volgorde essentieel is.

Praktisch voorbeeld

Stel een betalingssysteem voor waarin elke transactie exact in de volgorde van binnenkomst moet worden verwerkt. Als betalingen buiten de volgorde worden afgehandeld, kan dit leiden tot fouten, zoals onjuiste saldo-berekeningen.

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); } }

Deze code simuleert een betalingsverwerkingssysteem waarbij transacties in de volgorde van binnenkomst moeten worden afgehandeld. Het gebruik van parallelStream() verhoogt de prestaties, maar forEachOrdered() zorgt ervoor dat de volgorde behouden blijft.

Prestatievergelijking: forEach() vs. forEachOrdered()

Hier wordt gemeten hoe veel sneller forEach() wordt uitgevoerd in vergelijking met forEachOrdered() bij het werken met parallelle streams. Hiervoor wordt een lijst van 10 miljoen elementen aangemaakt, verwerkt met beide methoden door de vierkantswortel van elk getal te berekenen, en de uitvoeringstijd geregistreerd.

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); } }

De methode forEach() verwerkt elementen zonder de volgorde te behouden, waardoor de stream de taken vrij kan verdelen over de beschikbare processorkernen. Dit maximaliseert de prestaties, omdat elke thread elementen in willekeurige volgorde kan oppakken en parallel kan verwerken zonder beperkingen.

De methode forEachOrdered() behoudt de oorspronkelijke volgorde van de elementen, wat extra synchronisatie vereist. In een parallelle stream worden elementen eerst opgesplitst in delen voor verwerking, maar hun resultaten moeten vervolgens in de juiste volgorde worden samengevoegd voordat ze aan de verwerkingsmethode worden doorgegeven.

1. Welke functionele interface accepteert de methode forEach?

2. Welke uitvoer kan deze code produceren?

question mark

Welke functionele interface accepteert de methode forEach?

Select the correct answer

question mark

Welke uitvoer kan deze code produceren?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 4
some-alt