Refactorizando con Streams

Java, Functional Programming, Refactoring, Learning


Hoy traigo una serie de ejemplos de refactorización a modo de introducción a las nuevas características funcionales de Java 8. Así que, si tenías curiosidad y no te habías atrevido a experimentar con ellas, ¡te animo a que pruebes!

Empezamos definiendo una clase Person básica con un nombre y una edad:

Una vez definida nuestra clase base, vamos a hacer un ejemplo sencillo: tenemos una lista de personas y queremos tener otra lista pero sólo con las personas que sean mayores de 22 años.

Y ahora usando Java 8:

Vamos a explicarlo un poco. Primero tenemos el método stream(), propio de las colecciones, que devuelve un Stream (conjunto inmutable de elementos y una serie de funciones con las que operar sobre el mismo). Seguimos con la función filter que, como su nombre indica, filtra los elementos a partir de un predicado (función que evalúa un argumento siendo el resultado verdadero o falso). Y por último_,_ tenemos que volver a transformar el stream en una lista, por lo que llamamos a la función collect y nos ayudamos de los Collectors para ello.

Podemos extraer el predicado en una variable para tener una mejor legibilidad:

Ahora pongamos otro ejemplo. Seguimos teniendo la misma lista de personas pero ahora queremos un String que contenga los nombres de las personas que sean menores de 22 años separados por ”, “.

Java 7:

Java 8:

En este ejemplo, vemos varias cosas nuevas como la función map, que devuelve un nuevo Stream del mismo tamaño, pero con la diferencia que cada elemento es el resultado de aplicar la función pasada por parámetro sobre cada uno de ellos (en este caso, me devuelve un Stream<String>. Además, vemos como podemos sustituir nuestra función lambda por una referencia al método, es  decir, hemos sustituído:

person -> person.name() por Person::name

Ya que queda más compacto y fácil de leer. Y por último, unimos todos los nombres separados por ”, “ sin tener que estar preocupándonos en si se nos añade o no una ”, “ de más.

A modo de conclusión, me gusta más ésta forma de programar declarativamente, ya que mejora mucho la legibilidad del código e incluso es más fácil de mantener. Ya vimos por ejemplo que, para reducir la lista de personas a una lista de nombres, bastó con añadir una línea llamando a la función map y listo.

Publicado originalmente en el blog de José Manuel Déniz.