Programación funcional en Java: técnicas avanzadas y Stream API

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Programación funcional en Java: nivel avanzado

\n\n

La programación funcional (PF) en Java ha dejado de ser simplemente una tendencia de moda: es una parte integral del lenguaje moderno desde la versión 8. Para los desarrolladores que han dominado las lambdas básicas y Stream API, llega la etapa en la que se requiere comprender conceptos más profundos: mónadas, composición de funciones, evaluación perezosa y estructuras de datos inmutables. Este artículo está dedicado a las técnicas avanzadas de programación funcional en Java que ayudarán a escribir código más limpio, predecible y seguro para la concurrencia.

\n\n

1. Composición de funciones y currificación

\n\n

En Java, las interfaces funcionales Function, Predicate y Consumer proporcionan métodos por defecto para la composición: andThen() y compose(). Esto permite construir cadenas de transformaciones sin crear variables intermedias.

\n\n

Ejemplo de composición:

\n
import java.util.function.Function;\n\npublic class FunctionComposition {\n    public static void main(String[] args) {\n        Function<String, String> trim = String::trim;\n        Function<String, String> toUpper = String::toUpperCase;\n        Function<String, String> addExclamation = s -> s + "!";\n\n        // Composición: trim -> toUpper -> addExclamation\n        Function<String, String> process = trim.andThen(toUpper).andThen(addExclamation);\n\n        String result = process.apply("  hello world  ");\n        System.out.println(result); // HELLO WORLD!\n    }\n}
\n\n

Currificación es la transformación de una función de varios argumentos en una secuencia de funciones de un solo argumento. En Java, esto se puede emular con lambdas anidadas:

\n\n
import java.util.function.Function;\n\npublic class CurryingExample {\n    // Función normal\n    static int add(int a, int b) { return a + b; }\n\n    // Versión currificada\n    static Function<Integer, Function<Integer, Integer>> curriedAdd = a -> b -> a + b;\n\n    public static void main(String[] args) {\n        // Aplicación parcial\n        Function<Integer, Integer> add5 = curriedAdd.apply(5);\n        System.out.println(add5.apply(3)); // 8\n        System.out.println(add5.apply(10)); // 15\n    }\n}
\n\n

La currificación es útil para crear funciones especializadas basadas en patrones generales, especialmente al trabajar con configuraciones.

\n\n

2. Trabajo avanzado con Stream API

\n\n

Stream API en Java no es solo un reemplazo de los bucles. Comprender sus capacidades avanzadas permite aumentar significativamente el rendimiento y la legibilidad del código.

\n\n

2.1. Streams paralelos y Spliterator

\n

Los streams paralelos utilizan ForkJoinPool. Sin embargo, su eficiencia depende del tamaño de los datos y la naturaleza de las operaciones. Para un control personalizado del paralelismo, se puede usar Spliterator.

\n\n
import java.util.Spliterator;\nimport java.util.stream.Stream;\nimport java.util.stream.StreamSupport;\n\npublic class CustomSpliterator {\n    public static void main(String[] args) {\n        // Creación de un stream a partir de un iterador con Spliterator personalizado\n        Spliterator<Integer> spliterator = new Spliterator<>() {\n            int current = 0;\n            @Override\n            public boolean tryAdvance(java.util.function.Consumer<? super Integer> action) {\n                if (current < 100) {\n                    action.accept(current++);\n                    return true;\n                }\n                return false;\n            }\n            @Override\n            public Spliterator<Integer> trySplit() {\n                // División más simple\n                int mid = current + 50;\n                if (mid >= 100) return null;\n                Spliterator<Integer> prefix = new RangeSpliterator(curre                

Blogs

Book Recommendations