Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lära Bearbetning av element med forEach()-metoden | Terminaloperationer i Stream API
Stream API

bookBearbetning av element med forEach()-metoden

Du är redan bekant med metoden forEach() eftersom du har använt den i praktiken för att skriva ut varje element i en samling till konsolen. Låt oss titta närmare på den och utforska dess implementationer.

Den erbjuder ett bekvämt sätt att bearbeta data i en funktionell stil. Det är dock viktigt att notera att bearbetningsordningen beror på strömtypen och den använda metoden.

Det finns två implementationer av metoden forEach() i Stream API. Låt oss gå igenom dem en i taget.

forEach-metoden

Utför en åtgärd på varje element, men bearbetningsordningen garanteras inte i parallella strömmar.

void forEach(Consumer<? super T> action)

Metoden forEach() tar en Consumer<T> som argument—ett funktionellt gränssnitt som definierar en operation för varje element i strömmen. Den används ofta för loggning, utskrift eller för att utföra bieffekter.

Praktiskt exempel

I en webbutik behöver användare få notiser om personliga rabatter. Eftersom ordningen inte spelar någon roll används forEach() med en parallell ström för snabbare exekvering.

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

Denna kod simulerar utskick av personliga rabattmejl till kunder. Eftersom parallelStream() används skickas mejlen i ingen särskild ordning för förbättrad hastighet. Metoden forEach() tillämpar den angivna åtgärden på varje mejl.

forEachOrdered-metoden

Utför en åtgärd samtidigt som ordningen på elementen bevaras, även i parallella strömmar.

void forEachOrdered(Consumer<? super T> action)

Precis som forEach accepterar denna metod också en Consumer<T>, men den säkerställer att elementen behandlas i samma ordning som de förekommer i den ursprungliga strömmen. Detta är användbart när det är avgörande att behålla sekvensen.

Praktiskt exempel

Föreställ dig ett betalningssystem där varje transaktion måste behandlas i exakt den ordning den anländer. Om betalningar hanteras i fel ordning kan det leda till fel, såsom felaktiga saldoberekingar.

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

Denna kod simulerar ett betalningshanteringssystem där transaktioner måste behandlas i den ordning de anländer. Användningen av parallelStream() ökar prestandan, men forEachOrdered() säkerställer att sekvensen förblir intakt.

Prestandajämförelse: forEach() vs. forEachOrdered()

Låt oss mäta hur mycket snabbare forEach() körs jämfört med forEachOrdered() vid arbete med parallella strömmar. För att göra detta skapar du en lista med 10 miljoner element, behandlar dem med båda metoderna genom att beräkna kvadratroten av varje tal och registrerar exekveringstiden.

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

forEach()-metoden bearbetar element utan att bevara ordningen, vilket gör att strömmen fritt kan fördela uppgifter över tillgängliga processorkärnor. Detta maximerar prestanda, eftersom varje tråd kan välja element i valfri ordning och bearbeta dem parallellt utan begränsningar.

Metoden forEachOrdered() bevarar ursprunglig ordningelementen, vilket kräver ytterligare synkronisering. I en parallell ström delas elementen först upp i delar för bearbetning, men deras resultat måste sedan sättas ihop i rätt ordning innan de skickas vidare till bearbetningsmetoden.

1. Vilket funktionellt gränssnitt accepterar metoden forEach?

2. Vilket utdata kan denna kod producera?

question mark

Vilket funktionellt gränssnitt accepterar metoden forEach?

Select the correct answer

question mark

Vilket utdata kan denna kod producera?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 3. Kapitel 4

Fråga AI

expand

Fråga AI

ChatGPT

Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal

Awesome!

Completion rate improved to 2.33

bookBearbetning av element med forEach()-metoden

Svep för att visa menyn

Du är redan bekant med metoden forEach() eftersom du har använt den i praktiken för att skriva ut varje element i en samling till konsolen. Låt oss titta närmare på den och utforska dess implementationer.

Den erbjuder ett bekvämt sätt att bearbeta data i en funktionell stil. Det är dock viktigt att notera att bearbetningsordningen beror på strömtypen och den använda metoden.

Det finns två implementationer av metoden forEach() i Stream API. Låt oss gå igenom dem en i taget.

forEach-metoden

Utför en åtgärd på varje element, men bearbetningsordningen garanteras inte i parallella strömmar.

void forEach(Consumer<? super T> action)

Metoden forEach() tar en Consumer<T> som argument—ett funktionellt gränssnitt som definierar en operation för varje element i strömmen. Den används ofta för loggning, utskrift eller för att utföra bieffekter.

Praktiskt exempel

I en webbutik behöver användare få notiser om personliga rabatter. Eftersom ordningen inte spelar någon roll används forEach() med en parallell ström för snabbare exekvering.

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

Denna kod simulerar utskick av personliga rabattmejl till kunder. Eftersom parallelStream() används skickas mejlen i ingen särskild ordning för förbättrad hastighet. Metoden forEach() tillämpar den angivna åtgärden på varje mejl.

forEachOrdered-metoden

Utför en åtgärd samtidigt som ordningen på elementen bevaras, även i parallella strömmar.

void forEachOrdered(Consumer<? super T> action)

Precis som forEach accepterar denna metod också en Consumer<T>, men den säkerställer att elementen behandlas i samma ordning som de förekommer i den ursprungliga strömmen. Detta är användbart när det är avgörande att behålla sekvensen.

Praktiskt exempel

Föreställ dig ett betalningssystem där varje transaktion måste behandlas i exakt den ordning den anländer. Om betalningar hanteras i fel ordning kan det leda till fel, såsom felaktiga saldoberekingar.

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

Denna kod simulerar ett betalningshanteringssystem där transaktioner måste behandlas i den ordning de anländer. Användningen av parallelStream() ökar prestandan, men forEachOrdered() säkerställer att sekvensen förblir intakt.

Prestandajämförelse: forEach() vs. forEachOrdered()

Låt oss mäta hur mycket snabbare forEach() körs jämfört med forEachOrdered() vid arbete med parallella strömmar. För att göra detta skapar du en lista med 10 miljoner element, behandlar dem med båda metoderna genom att beräkna kvadratroten av varje tal och registrerar exekveringstiden.

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

forEach()-metoden bearbetar element utan att bevara ordningen, vilket gör att strömmen fritt kan fördela uppgifter över tillgängliga processorkärnor. Detta maximerar prestanda, eftersom varje tråd kan välja element i valfri ordning och bearbeta dem parallellt utan begränsningar.

Metoden forEachOrdered() bevarar ursprunglig ordningelementen, vilket kräver ytterligare synkronisering. I en parallell ström delas elementen först upp i delar för bearbetning, men deras resultat måste sedan sättas ihop i rätt ordning innan de skickas vidare till bearbetningsmetoden.

1. Vilket funktionellt gränssnitt accepterar metoden forEach?

2. Vilket utdata kan denna kod producera?

question mark

Vilket funktionellt gränssnitt accepterar metoden forEach?

Select the correct answer

question mark

Vilket utdata kan denna kod producera?

Select the correct answer

Var allt tydligt?

Hur kan vi förbättra det?

Tack för dina kommentarer!

Avsnitt 3. Kapitel 4
some-alt