Aggregating av Element med reduce()-Metoden
Vid arbete med samlingar i Java behöver du ofta reducera alla element till ett enda resultat, såsom en summa, produkt eller ett annat aggregerat värde.
Det finns tre varianter av metoden reduce(), var och en utformad för olika scenarier. Låt oss gå igenom varje variant i detalj.
reduce() med en enda parameter
Om du behöver aggregatera element utan ett initialvärde kan du använda denna version av reduce(). Eftersom strömmen kan vara tom returnerar dock metoden en Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Denna metod tillämpar funktionen accumulator på alla element i strömmen och returnerar en Optional<T>.
Praktiskt exempel
Föreställ dig en webbutik med en lista över produkter och deras priser. Målet är att beräkna den totala intäkten för alla produkter i butiken.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738package com.example; import java.util.List; import java.util.Optional; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); Optional<Double> totalRevenue = products.stream() .map(Product::getPrice) .reduce(Double::sum); totalRevenue.ifPresent(revenue -> System.out.println("Total revenue: " + revenue)); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Denna kod skapar en lista av produkter och använder sedan reduce() för att summera priserna. Metoden map(Product::getPrice) extraherar priset för varje produkt, medan Double::sum utför summeringen. Om resultatet är närvarande skrivs det ut.
reduce() med två parametrar
Om du vill säkerställa ett garanterat returvärde, även när strömmen är tom, använd reduce()-metoden med en identitetsparameter. Startvärdet säkerställer en stabil beräkning.
T reduce(T identity, BinaryOperator<T> accumulator);
Denna version av reduce() börjar med det angivna identity-värdet, vilket säkerställer att ett resultat alltid returneras, även för en tom stream.
Praktiskt exempel
Antag att en butik har en kassa med ett initialt saldo, och du behöver addera det totala priset för alla produkter för att fastställa det potentiella totala kassabeloppet.
Main.java
12345678910111213141516171819202122232425262728293031323334353637package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); double totalRevenue = products.stream() .map(Product::getPrice) .reduce(500.0, Double::sum); System.out.println("Total revenue with initial balance: " + totalRevenue); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Här extraherar koden priser med map(Product::getPrice) och tillämpar reduce(500.0, Double::sum), där 500.0 representerar startbalansen och Double::sum summerar värdena.
reduce() för parallell bearbetning
Denna version av reduce() är avsedd för situationer där mer komplexa transformationer krävs och resultat behöver sammanställas i parallell.
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Denna metod tar tre parametrar:
identity– initialvärde;accumulator– en funktion som transformerar varje element;combiner– en funktion som slår samman delresultat.
Praktiskt exempel
I en webbutik behöver du beräkna det totala antalet tecken i alla produktnamn. Detta kan vara användbart för att sätta begränsningar på kvitto-längd.
Main.java
123456789101112131415161718192021222324252627282930313233343536package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); int totalLength = products.stream() .reduce(0, (sum, product) -> sum + product.getName().length(), Integer::sum); System.out.println("Total name length: " + totalLength); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Koden itererar genom listan av produkter med hjälp av reduce(), där 0 är startvärdet, (sum, product) -> sum + product.getName().length() definierar logiken för att summera produktnamnens längder, och Integer::sum kombinerar resultaten i en parallell bearbetningsmiljö.
1. Vilken datatyp returnerar reduce(BinaryOperator<T> accumulator) om streamen kan vara tom?
2. När bör du använda reduce(T identity, BinaryOperator<T> accumulator)?
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
Can you show me code examples for each reduce() variation?
What are some common use cases for each reduce() method?
Can you explain the difference between Optional<T> and T in the reduce() results?
Awesome!
Completion rate improved to 2.33
Aggregating av Element med reduce()-Metoden
Svep för att visa menyn
Vid arbete med samlingar i Java behöver du ofta reducera alla element till ett enda resultat, såsom en summa, produkt eller ett annat aggregerat värde.
Det finns tre varianter av metoden reduce(), var och en utformad för olika scenarier. Låt oss gå igenom varje variant i detalj.
reduce() med en enda parameter
Om du behöver aggregatera element utan ett initialvärde kan du använda denna version av reduce(). Eftersom strömmen kan vara tom returnerar dock metoden en Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Denna metod tillämpar funktionen accumulator på alla element i strömmen och returnerar en Optional<T>.
Praktiskt exempel
Föreställ dig en webbutik med en lista över produkter och deras priser. Målet är att beräkna den totala intäkten för alla produkter i butiken.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738package com.example; import java.util.List; import java.util.Optional; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); Optional<Double> totalRevenue = products.stream() .map(Product::getPrice) .reduce(Double::sum); totalRevenue.ifPresent(revenue -> System.out.println("Total revenue: " + revenue)); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Denna kod skapar en lista av produkter och använder sedan reduce() för att summera priserna. Metoden map(Product::getPrice) extraherar priset för varje produkt, medan Double::sum utför summeringen. Om resultatet är närvarande skrivs det ut.
reduce() med två parametrar
Om du vill säkerställa ett garanterat returvärde, även när strömmen är tom, använd reduce()-metoden med en identitetsparameter. Startvärdet säkerställer en stabil beräkning.
T reduce(T identity, BinaryOperator<T> accumulator);
Denna version av reduce() börjar med det angivna identity-värdet, vilket säkerställer att ett resultat alltid returneras, även för en tom stream.
Praktiskt exempel
Antag att en butik har en kassa med ett initialt saldo, och du behöver addera det totala priset för alla produkter för att fastställa det potentiella totala kassabeloppet.
Main.java
12345678910111213141516171819202122232425262728293031323334353637package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); double totalRevenue = products.stream() .map(Product::getPrice) .reduce(500.0, Double::sum); System.out.println("Total revenue with initial balance: " + totalRevenue); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Här extraherar koden priser med map(Product::getPrice) och tillämpar reduce(500.0, Double::sum), där 500.0 representerar startbalansen och Double::sum summerar värdena.
reduce() för parallell bearbetning
Denna version av reduce() är avsedd för situationer där mer komplexa transformationer krävs och resultat behöver sammanställas i parallell.
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Denna metod tar tre parametrar:
identity– initialvärde;accumulator– en funktion som transformerar varje element;combiner– en funktion som slår samman delresultat.
Praktiskt exempel
I en webbutik behöver du beräkna det totala antalet tecken i alla produktnamn. Detta kan vara användbart för att sätta begränsningar på kvitto-längd.
Main.java
123456789101112131415161718192021222324252627282930313233343536package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); int totalLength = products.stream() .reduce(0, (sum, product) -> sum + product.getName().length(), Integer::sum); System.out.println("Total name length: " + totalLength); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }
Koden itererar genom listan av produkter med hjälp av reduce(), där 0 är startvärdet, (sum, product) -> sum + product.getName().length() definierar logiken för att summera produktnamnens längder, och Integer::sum kombinerar resultaten i en parallell bearbetningsmiljö.
1. Vilken datatyp returnerar reduce(BinaryOperator<T> accumulator) om streamen kan vara tom?
2. När bör du använda reduce(T identity, BinaryOperator<T> accumulator)?
Tack för dina kommentarer!