El concepto de Java Stream Reduce , es uno de los más importantes a nivel de programación funcional ya que cubre las operaciones de Reducción que nos permiten convertir una lista de elementos X en un resultado Y . Esto en un principio nos puede parecer un poco curioso pero es bastante útil.
Vamos a ver un ejemplo sencillo supongamos que disponemos de una lista de gastos y queremos calcular su total. Normalmente en una situación clásica deberíamos utilizar un bucle for .
package com.arquitecturajava; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; public class Principal4 { public static void main(String[] args) { List<Integer> gastos= new ArrayList<Integer>(); int total=0; gastos.add(100); gastos.add(200); gastos.add(300); for(int gasto : gastos) { total+=gasto; } System.out.println(total); } }
el resultado lo podemos ver salir por la consola:
600
Java Stream Reduce
Gracias a la programación funcional podemos realizar estas operaciones de una forma muy diferente nos podemos apoyar en el método reduce que recibe 2 parámetros un acumulador como primero y un elemento como segundo .
De esta forma realiza una funcionalidad de “reducción” convirtiendo una lista de elementos en un único resultado.
Vamos a verlo en código :
package com.arquitecturajava; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; public class Principal3 { public static void main(String[] args) { List<Integer> gastos= new ArrayList<Integer>(); gastos.add(100); gastos.add(200); gastos.add(300); gastos.stream().reduce((acumulador,numero)-> { return acumulador+numero; }).ifPresent(System.out::println); }
Simplificación de sintaxis
Esto nos permite realizar la misma operación y obtener el mismo resultado pero realizando un ejemplo de programación funcional. Todavía lo podemos simplificar más ya que podríamos delegar en la clase Integer y en su reference method de sum que realiza la misma operación.
gastos.stream().reduce(Integer::sum).ifPresent(System.out::println);
De igual manera que usamos el método de reducción para sumar números podemos usarlo también por ejemplo para combinar cadenas.
package com.arquitecturajava; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Stream; public class Principal4 { public static void main(String[] args) { List<String> nombres= new ArrayList<String>(); nombres.add("juan"); nombres.add("gema"); nombres.add("maria"); nombres.stream().reduce(String::concat).ifPresent(System.out::println); } }
El uso de Java Stream Reduce nos puede ayudar en muchas situaciones a eliminar bucles y abordar situaciones de programación funcional que de otra forma serían complejas.
tendras algun ejemplo de como sacar un promedio de una lista de objetos?
No lo tengo ya lo siento 🙁
puedes hacer la suma de los elementos con la funcion sum y de alli solo faltaria dividir ese valor para la cantidad de elementos en el objeto (object.size o object.length)
si es una opción más compacta ,claramente , gracias por el aporte 🙂
Gracias por el artículo, para los que no lo conocíamos es bastante útil.
Una duda que me surge, veo que el acumulador no se inicializa, ya viene hecho de alguna parte.
Me imagino que usara el constructor por defecto.
¿Hay alguna manera de que el acumulador lo puedas inicializar tu, para que tenga un estado deseado?
Sino recuerdo mal es uno de los parámetros q admite la sobrecarga
Recién estoy aprendiendo este interesante tema y respondiendo creo que sería así:
gastos.stream().reduce(10,Integer::sum).ifPresent(System.out::println);
El acumulador estoy inicializando en 10, corríjanme si estoy mal.
si