Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Agregación de Elementos con el Método reduce() | Operaciones Terminales en la Stream API
Stream API

bookAgregación de Elementos con el Método reduce()

Al trabajar con colecciones en Java, a menudo es necesario reducir todos los elementos a un solo resultado, como una suma, producto u otro valor agregado.

Existen tres variantes del método reduce(), cada una diseñada para diferentes escenarios. A continuación, se explica cada una en detalle.

reduce() con un solo parámetro

Si se requiere agregar elementos sin un valor inicial, se puede utilizar esta versión de reduce(). Sin embargo, dado que el flujo puede estar vacío, el método devuelve un Optional<T>.

Optional<T> reduce(BinaryOperator<T> accumulator);

Este método aplica la función accumulator a todos los elementos del flujo y devuelve un Optional<T>.

Ejemplo práctico

Suponga una tienda en línea con una lista de productos y sus precios. El objetivo es calcular el ingreso total de todos los productos en la tienda.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738
package 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; } }

Este código crea una lista de productos y luego utiliza reduce() para sumar los precios. El método map(Product::getPrice) extrae el precio de cada producto, mientras que Double::sum realiza la sumatoria. Si el resultado está presente, se imprime.

reduce() con dos parámetros

Para garantizar un valor de retorno incluso cuando el stream está vacío, utiliza el método reduce() con un parámetro de identidad. El valor inicial asegura un cálculo estable.

T reduce(T identity, BinaryOperator<T> accumulator);

Esta versión de reduce() comienza con el valor identity proporcionado, lo que garantiza que siempre se devuelva un resultado, incluso para un stream vacío.

Ejemplo práctico

Suponga que una tienda tiene una caja registradora con un saldo inicial, y es necesario sumar el precio total de todos los productos para determinar el potencial total de efectivo disponible.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031323334353637
package 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; } }

Aquí, el código extrae los precios con map(Product::getPrice) y aplica reduce(500.0, Double::sum), donde 500.0 representa el saldo inicial, y Double::sum suma los valores.

reduce() para procesamiento en paralelo

Esta versión de reduce() está diseñada para casos donde se requieren transformaciones más complejas y los resultados deben ser agregados en paralelo.

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

Este método toma tres parámetros:

  • identity – el valor inicial;
  • accumulator – una función que transforma cada elemento;
  • combiner – una función que fusiona los resultados parciales.

Ejemplo práctico

En una tienda en línea, es necesario calcular el número total de caracteres en todos los nombres de productos. Esto puede ser útil para establecer límites en la longitud del recibo.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536
package 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; } }

El código itera a través de la lista de productos utilizando reduce(), donde 0 es el valor inicial, (sum, product) -> sum + product.getName().length() define la lógica para sumar las longitudes de los nombres de los productos, y Integer::sum combina los resultados en un entorno de procesamiento paralelo.

1. ¿Qué tipo de dato retorna reduce(BinaryOperator<T> accumulator) si el stream puede estar vacío?

2. ¿Cuándo se debe utilizar reduce(T identity, BinaryOperator<T> accumulator)?

question mark

¿Qué tipo de dato retorna reduce(BinaryOperator<T> accumulator) si el stream puede estar vacío?

Select the correct answer

question mark

¿Cuándo se debe utilizar reduce(T identity, BinaryOperator<T> accumulator)?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 6

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Suggested prompts:

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

bookAgregación de Elementos con el Método reduce()

Desliza para mostrar el menú

Al trabajar con colecciones en Java, a menudo es necesario reducir todos los elementos a un solo resultado, como una suma, producto u otro valor agregado.

Existen tres variantes del método reduce(), cada una diseñada para diferentes escenarios. A continuación, se explica cada una en detalle.

reduce() con un solo parámetro

Si se requiere agregar elementos sin un valor inicial, se puede utilizar esta versión de reduce(). Sin embargo, dado que el flujo puede estar vacío, el método devuelve un Optional<T>.

Optional<T> reduce(BinaryOperator<T> accumulator);

Este método aplica la función accumulator a todos los elementos del flujo y devuelve un Optional<T>.

Ejemplo práctico

Suponga una tienda en línea con una lista de productos y sus precios. El objetivo es calcular el ingreso total de todos los productos en la tienda.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738
package 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; } }

Este código crea una lista de productos y luego utiliza reduce() para sumar los precios. El método map(Product::getPrice) extrae el precio de cada producto, mientras que Double::sum realiza la sumatoria. Si el resultado está presente, se imprime.

reduce() con dos parámetros

Para garantizar un valor de retorno incluso cuando el stream está vacío, utiliza el método reduce() con un parámetro de identidad. El valor inicial asegura un cálculo estable.

T reduce(T identity, BinaryOperator<T> accumulator);

Esta versión de reduce() comienza con el valor identity proporcionado, lo que garantiza que siempre se devuelva un resultado, incluso para un stream vacío.

Ejemplo práctico

Suponga que una tienda tiene una caja registradora con un saldo inicial, y es necesario sumar el precio total de todos los productos para determinar el potencial total de efectivo disponible.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031323334353637
package 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; } }

Aquí, el código extrae los precios con map(Product::getPrice) y aplica reduce(500.0, Double::sum), donde 500.0 representa el saldo inicial, y Double::sum suma los valores.

reduce() para procesamiento en paralelo

Esta versión de reduce() está diseñada para casos donde se requieren transformaciones más complejas y los resultados deben ser agregados en paralelo.

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

Este método toma tres parámetros:

  • identity – el valor inicial;
  • accumulator – una función que transforma cada elemento;
  • combiner – una función que fusiona los resultados parciales.

Ejemplo práctico

En una tienda en línea, es necesario calcular el número total de caracteres en todos los nombres de productos. Esto puede ser útil para establecer límites en la longitud del recibo.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536
package 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; } }

El código itera a través de la lista de productos utilizando reduce(), donde 0 es el valor inicial, (sum, product) -> sum + product.getName().length() define la lógica para sumar las longitudes de los nombres de los productos, y Integer::sum combina los resultados en un entorno de procesamiento paralelo.

1. ¿Qué tipo de dato retorna reduce(BinaryOperator<T> accumulator) si el stream puede estar vacío?

2. ¿Cuándo se debe utilizar reduce(T identity, BinaryOperator<T> accumulator)?

question mark

¿Qué tipo de dato retorna reduce(BinaryOperator<T> accumulator) si el stream puede estar vacío?

Select the correct answer

question mark

¿Cuándo se debe utilizar reduce(T identity, BinaryOperator<T> accumulator)?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 6
some-alt