Aggregazione degli Elementi con il Metodo reduce()
Quando si lavora con le collezioni in Java, spesso è necessario ridurre tutti gli elementi a un unico risultato, come una somma, un prodotto o un altro valore aggregato.
Esistono tre varianti del metodo reduce(), ciascuna progettata per diversi scenari. Analizziamole nel dettaglio.
reduce() con un solo parametro
Se è necessario aggregare elementi senza un valore iniziale, è possibile utilizzare questa versione di reduce(). Tuttavia, poiché lo stream potrebbe essere vuoto, il metodo restituisce un Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Questo metodo applica la funzione accumulator a tutti gli elementi dello stream e restituisce un Optional<T>.
Esempio pratico
Si consideri un negozio online con un elenco di prodotti e i relativi prezzi. L'obiettivo è calcolare il fatturato totale di tutti i prodotti presenti nel negozio.
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; } }
Questo codice crea una lista di prodotti, quindi utilizza reduce() per sommare i prezzi. Il metodo map(Product::getPrice) estrae il prezzo di ciascun prodotto, mentre Double::sum esegue la somma. Se il risultato è presente, viene stampato.
reduce() con Due Parametri
Se si desidera garantire un valore di ritorno, anche quando lo stream è vuoto, utilizzare il metodo reduce() con un parametro identità. Il valore iniziale assicura un calcolo stabile.
T reduce(T identity, BinaryOperator<T> accumulator);
Questa versione di reduce() inizia con il valore identity fornito, garantendo che venga sempre restituito un risultato, anche per uno stream vuoto.
Esempio pratico
Si supponga che un negozio disponga di una cassa con un saldo iniziale e sia necessario sommare il prezzo totale di tutti i prodotti per determinare il potenziale totale di denaro disponibile.
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; } }
Qui, il codice estrae i prezzi con map(Product::getPrice) e applica reduce(500.0, Double::sum), dove 500.0 rappresenta il saldo iniziale e Double::sum somma i valori.
reduce() per l'elaborazione parallela
Questa versione di reduce() è progettata per casi in cui sono necessarie trasformazioni più complesse e i risultati devono essere aggregati in parallelo.
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Questo metodo accetta tre parametri:
identity– il valore iniziale;accumulator– una funzione che trasforma ciascun elemento;combiner– una funzione che unisce i risultati parziali.
Esempio pratico
In un negozio online, è necessario calcolare il numero totale di caratteri in tutti i nomi dei prodotti. Questo può essere utile per impostare limiti sulla lunghezza dello scontrino.
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; } }
Il codice itera attraverso la lista di prodotti utilizzando reduce(), dove 0 rappresenta il valore iniziale, (sum, product) -> sum + product.getName().length() definisce la logica per sommare le lunghezze dei nomi dei prodotti, e Integer::sum combina i risultati in un ambiente di elaborazione parallela.
1. Quale tipo di dato restituisce reduce(BinaryOperator<T> accumulator) se lo stream potrebbe essere vuoto?
2. Quando si dovrebbe utilizzare reduce(T identity, BinaryOperator<T> accumulator)?
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione
Awesome!
Completion rate improved to 2.33
Aggregazione degli Elementi con il Metodo reduce()
Scorri per mostrare il menu
Quando si lavora con le collezioni in Java, spesso è necessario ridurre tutti gli elementi a un unico risultato, come una somma, un prodotto o un altro valore aggregato.
Esistono tre varianti del metodo reduce(), ciascuna progettata per diversi scenari. Analizziamole nel dettaglio.
reduce() con un solo parametro
Se è necessario aggregare elementi senza un valore iniziale, è possibile utilizzare questa versione di reduce(). Tuttavia, poiché lo stream potrebbe essere vuoto, il metodo restituisce un Optional<T>.
Optional<T> reduce(BinaryOperator<T> accumulator);
Questo metodo applica la funzione accumulator a tutti gli elementi dello stream e restituisce un Optional<T>.
Esempio pratico
Si consideri un negozio online con un elenco di prodotti e i relativi prezzi. L'obiettivo è calcolare il fatturato totale di tutti i prodotti presenti nel negozio.
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; } }
Questo codice crea una lista di prodotti, quindi utilizza reduce() per sommare i prezzi. Il metodo map(Product::getPrice) estrae il prezzo di ciascun prodotto, mentre Double::sum esegue la somma. Se il risultato è presente, viene stampato.
reduce() con Due Parametri
Se si desidera garantire un valore di ritorno, anche quando lo stream è vuoto, utilizzare il metodo reduce() con un parametro identità. Il valore iniziale assicura un calcolo stabile.
T reduce(T identity, BinaryOperator<T> accumulator);
Questa versione di reduce() inizia con il valore identity fornito, garantendo che venga sempre restituito un risultato, anche per uno stream vuoto.
Esempio pratico
Si supponga che un negozio disponga di una cassa con un saldo iniziale e sia necessario sommare il prezzo totale di tutti i prodotti per determinare il potenziale totale di denaro disponibile.
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; } }
Qui, il codice estrae i prezzi con map(Product::getPrice) e applica reduce(500.0, Double::sum), dove 500.0 rappresenta il saldo iniziale e Double::sum somma i valori.
reduce() per l'elaborazione parallela
Questa versione di reduce() è progettata per casi in cui sono necessarie trasformazioni più complesse e i risultati devono essere aggregati in parallelo.
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
Questo metodo accetta tre parametri:
identity– il valore iniziale;accumulator– una funzione che trasforma ciascun elemento;combiner– una funzione che unisce i risultati parziali.
Esempio pratico
In un negozio online, è necessario calcolare il numero totale di caratteri in tutti i nomi dei prodotti. Questo può essere utile per impostare limiti sulla lunghezza dello scontrino.
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; } }
Il codice itera attraverso la lista di prodotti utilizzando reduce(), dove 0 rappresenta il valore iniziale, (sum, product) -> sum + product.getName().length() definisce la logica per sommare le lunghezze dei nomi dei prodotti, e Integer::sum combina i risultati in un ambiente di elaborazione parallela.
1. Quale tipo di dato restituisce reduce(BinaryOperator<T> accumulator) se lo stream potrebbe essere vuoto?
2. Quando si dovrebbe utilizzare reduce(T identity, BinaryOperator<T> accumulator)?
Grazie per i tuoi commenti!