Introducción a la programación Funcional

1

Programación Funcional en Java: Conceptos y Aplicaciones Prácticas

Entendiendo las partes de la programación funcional

2

Funciones en Programación Funcional: Conceptos Básicos

3

Funciones como Ciudadanos de Primera Clase en Programación

4

Funciones Puras: Concepto y Ejemplos Prácticos

5

Efectos Secundarios en Programación y su Impacto en el Código

6

Funciones de Orden Superior en Programación

7

Funciones Lambda en Programación Funcional Java

8

Inmutabilidad de Datos en Programación Funcional con Java

Functional Programming en Java

9

Programación Funcional en Java SE: Conceptos y Prácticas

10

Programación Funcional en Java: Práctica y Ejemplos en IntelliJ

11

Programación Funcional en Java: Creación y Uso de Funciones

12

Programación Funcional con Predicados en Java

13

Interfaz Consumer y Supplier en Java: Uso y Ejemplos Prácticos

14

Funciones Java para Transformación de Datos y Operaciones Binarias

15

Creación y Uso de Interfaces Funcionales Personalizadas en Java

16

Métodos de Referencia en Programación Funcional Java

17

Inferencia de tipos en Java: funciones y métodos

18

Uso de Expresiones Lambda en Java: Sintaxis y Aplicaciones

19

Interfaz Funcional en Java: Creación y Uso de Métodos Default

20

Encadenamiento de Llamadas en Programación Orientada a Objetos

21

Composición de Funciones en Programación Funcional

Optional y Streams: Datos mas interesantes

22

Uso de la Clase Optional en Java para Manejo de Valores Nulos

23

Manipulación de Streams en Java: Operaciones y Limitaciones

24

Programación Funcional en Java: Uso de Streams y Operaciones Terminales

25

Operaciones de Stream en Java: Intermedias y Finales

26

Operaciones y Concurrente con Stream en Java

27

Operaciones Terminales en Java Streams

28

Operaciones Intermedias en Streams de Java

29

Conversión de Strings a Listas de Enteros en Java

Todo junto: Proyecto Job-search

30

Construcción de Proyecto para Buscar Empleo Usando APIs

31

Configuración y Uso de Gradle en Proyectos Java con IntelliJ

32

Creación de una Herramienta de Búsqueda de Trabajo en Terminal

33

Creación de Puntos de Entrada y Dependencias en Proyectos Java

34

Creación de APIs RESTful con Feign y Spring Boot

35

Creación de una Interfaz de Línea de Comandos con JCommander

36

Validación de Argumentos en Terminal con Clases en Ciel

37

Procesamiento de Argumentos y Solicitudes API en Java

38

Creación de API para búsqueda de empleos con Java y CLI

Conclusiones

39

Programación Funcional en Java: Conceptos y Aplicaciones

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Creación y Uso de Interfaces Funcionales Personalizadas en Java

15/39
Recursos

¿Cómo definir clases y funciones personalizadas en Java?

Para los desarrolladores de Java, la creación de clases y funciones personalizadas puede ser un camino fascinante para extender las funcionalidades de este lenguaje. Java, con el paquete java.util.function, ofrece la capacidad de definir interfaces funcionales y abstractas. Esto nos da la libertad de crear métodos y estructuras únicas para resolver problemas específicos o mejorar las capacidades de nuestro código. Vamos a explorar cómo hacerlo.

¿Qué es una interfaz SAM en Java?

En Java, una interfaz SAM (Single Abstract Method) es aquella que contiene un único método abstracto definido. Este concepto es crucial ya que permite el uso de expresiones lambda, proporcionando un enfoque más limpio y eficiente para escribir funciones anónimas.

  • Definición: Una interfaz SAM tiene un solo método abstracto que requiere implementación.
  • Ejemplo: Si definimos una interfaz funcional con un único método, esta puede ser utilizada como una función.

Java introdujo en la versión 8, la anotación @FunctionalInterface para mostrar que una interfaz es funcional. Sin embargo, si añadimos más métodos abstractos a la interfaz, dejaría de ser funcional, y el compilador nos arrojaría un error.

¿Cómo crear una TriFunction en Java?

Para ilustrar el uso de interfaces personalizadas, crearemos una interfaz llamada TriFunction que trabajará con tres parámetros de entrada de diferentes tipos y un tipo de salida. Por ejemplo, puede ser útil para calcular fechas o edades.

@FunctionalInterface
public interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}

Esta declaración define una interfaz que recibe tres tipos genéricos T, U, y V, y retorna un tipo R. Podemos implementar esta interfaz para crear funciones que manejen múltiples parámetros con lógica personalizada.

¿Cómo transformar enteros en fechas con lambda?

Supongamos que necesitamos convertir tres números enteros en una fecha, podemos utilizar nuestra TriFunction para esta tarea.

TriFunction<Integer, Integer, Integer, LocalDate> createLocalDate = 
    (day, month, year) -> LocalDate.parse(year + "-" + month + "-" + day, DateTimeFormatter.ofPattern("yyyy-M-d"));
  • Usamos LocalDate.parse: Este método nos permite convertir una cadena de texto en un objeto LocalDate.
  • DateTimeFormatter: Para asegurar que la cadena se interpreta correctamente, usamos un DateTimeFormatter con el patrón adecuado.

¿Cómo calcular la edad de una persona?

Extendiéndonos más allá de la conversión básica, podemos calcular la edad de una persona utilizando las funciones que hemos implementado. Imaginemos que queremos saber cuántos años han pasado desde una fecha específica hasta hoy.

TriFunction<Integer, Integer, Integer, Integer> calculateAge = 
    (day, month, year) -> {
        LocalDate birthDate = createLocalDate.apply(day, month, year);
        return Period.between(birthDate, LocalDate.now()).getYears();
    };

Al calcular la edad, es fundamental asegurarnos de que los días y meses menores a 10 estén correctamente formateados para evitar errores en la conversión.

¿Cómo asegurar el formato correcto en las fechas?

Para manejar adecuadamente los días y meses con un solo dígito, añadimos una función que añade un cero a la izquierda cuando es necesario.

Function<Integer, String> addLeadingZero = x -> (x < 10 ? "0" + x : x.toString());

Podemos utilizar esta función dentro de nuestras operaciones con fechas para asegurar el formato correcto:

String dayFormatted = addLeadingZero.apply(day);
String monthFormatted = addLeadingZero.apply(month);

Reflexión final sobre interfaces y funciones en Java

Definir interfaces funcionales como TriFunction y aplicar lambda expressions, no solo simplifica nuestro código, sino que también lo hace más modular y reutilizable. Podemos definir funciones extremadamente específicas para nuestras necesidades mientras preservamos el mantenimiento y la claridad del código. ¡Continúa experimentando con estos conceptos y verás cómo mejora la fluidez de tu desarrollo en Java!

Aportes 30

Preguntas 7

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Notes:

  1. SAM is the abbreviation of Single Abstract Method.

  2. A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit. From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods. Runnable, ActionListener, Comparable are some of the examples of functional interfaces.Before Java 8, we had to create anonymous inner class objects or implement these interfaces.

  3. @FunctionalInterface annotation is used to ensure that the functional interface can’t have more than one abstract method. In case more than one abstract methods are present, the compiler flags an ‘Unexpected @FunctionalInterface annotation’ message. However, it is not mandatory to use this annotation.

Para evitar la validación de agregar ceros se puede mejorar utilizando el formateador de la siguiente forma:
String.format("%02d ", days);

Este curso me vuela el cerebro.

Interfaces SAM y FunctionalInterface

Java tiene incorporadas las interfaces necesarias para crear funciones que reciban uno o dos parámetros de tipos diferentes, pudiendo especificar también el tipo de retorno, pero también es posible definir interfaces personalizadas que cumplan la misma funcion, pero que permita la utilización de más parámetros o fijar su tipo para no tener que especificarlos al definirlas.

Para hacerlo, basta con crear una interfáz SAM (Single Abstract Method) y agregar la anotación @FunctionalInterface

Por ejemplo, se puede definir una interfaz que permita crear funciones con tres parámetros.

@FunctionalInterface
public interface TriFunction<T, U, V, R> {
    R apply(T t, U u, V v);
}

Su utilización es similar a Function.

//       si x ____ y
// entonces z ____ ?
TriFunction<Integer, Integer, Integer, Double> reglaDeTres = (x, y, z) -> Double.valueOf(y * z / x);

Double resultado = reglaDeTres.apply(5, 30, 15); // retorna 90

Muchas gracias instructor Sinuhé, entonces por medio del uso de SAM y FunctionalInterface tendremos una forma de crear funciones que utilicen más de dos parámetros de ingreso.

Buenas, durante el vídeo el profesor indica que lo que vamos a calcular la edad, pero existe un pequeño error en el código. Lo que nuestra función calculateAge hace es obtener la diferencia de días y con esto no se obtiene la edad. La corrección es muy simple, solo se tiene que remplazar el getDays por getYears

Les comparto como quedaría la modificación

TriFunction<Integer,Integer,Integer,Integer> calculateAge =
                (day, month, year) -> Period.between(
                            parseDate.apply(day, month, year),
                            LocalDate.now()
                        ).getYears();

O se utiliza LocalDate#of(int year, int month, int dayOfMonth) en lugar de un hack innecesario.

SAM --> Single Abstrab Method, Es una interfaz que tiene un solo método sin definir. Para ello decoramos con @FuctionalInterface. Nos permite crear nuestras propias funciones.

En mi caso getDays() no funciono de forma correcta, probe con getYears() y funciono sin problemas.

El orden de este curso me encanta, te va explicando muy bien los conceptos que son necesarios para los siguientes
En esta clase falto explicar que una SAM solo tiene un método abstracto al igual que una Functionl Interface. Pero en una functional interface además puedes definir métodos por defecto y métodos estáticos: ```js @FunctionalInterface public interface Calculadora { int operar(int a, int b); // Un método por defecto default void mostrarResultado(int resultado) { System.out.println("El resultado es: " + resultado); } // Un método estático static void mostrarMensaje() { System.out.println("Ejecutando operación..."); } } ```Para su implementación: ```js public class Main { public static void main(String[] args) { Calculadora suma = (a, b) -> a + b; int resultado = suma.operar(5, 3); suma.mostrarResultado(resultado); // Imprime: El resultado es: 8 Calculadora.mostrarMensaje(); // Imprime: Ejecutando operación... } } ```Por lo tanto toda SAM es una Functional Interface pero no toda Functional Interface es una SAM pues las Functional Interface puede tener mas métodos además del método abstracto.
Hola, no entendí la razon de agregar los ceros
Super interesante esta clase y las posibilidades que ofrece

en mi trifuncion tuve que usar applay xq apply no me deja.

“La anotación @FunctionalInterface no es estrictamente necesaria para que una interfaz sea funcional, pero proporciona una forma explícita de indicar las intenciones del programador. Además, el uso de la anotación permite que el compilador realice verificaciones adicionales, lo que ayuda a evitar errores al usar interfaces funcionales.”

now() = 2019

22:27

SAM es Single Abstract Method, es una interface que debe tener solo un método.

Functional Interface: para que un interface se vuelva funcional, tiene que ser una SAM, sino es así, Java no me va a dejar volverla funcional

Sin la anotacion tambien funciona.
en realidad el unico valor que le agrega la anotacion es que valida que tenga un solo metodo.

Aso no tenga la anotacion. sino si una intefaz solo tiene un metodo abtracto. es considerada funcional.

Vale entonces para hacer nuestras propias funciones Funcionales solo necesitamos de una interfaz y la anotación @FunctionalInterface que maravilla

Esta clase me encantó, muy útil esta información y el ejemplo está perfecto aplicando lo visto hasta ahora.

Esta clase fue colosal, me encantó.

en function addCeros que quiere decir el símbolo “?”

Muchas gracias

Genial 😃 gracias… me corrió sin problemas el ejercicio 😃

Bien, me encantó. Algo nuevo… 😉

Increible

public class AgeUtils {
    public static void main(String[] args) {
        Function<Integer, String> addZero = x -> x < 10 ? "0" + x : String.valueOf(x);

        ITryFunction<Integer, Integer, Integer, LocalDate> parseDate =
                (day, month, year) -> LocalDate.parse(year + "-" + addZero.apply(month) + "-" + addZero.apply(day));

        ITryFunction<Integer, Integer, Integer, Integer> calculateAge =
                (day, month, year) -> Period.between(parseDate.apply(day, month, year), LocalDate.now()).getYears();

        System.out.println(calculateAge.apply(13, 9, 1996));
    }

    @FunctionalInterface
    interface ITryFunction<T, U, V, R>{
        R apply(T t, U u, V v);
    }
}

Muy bien Explicado

Perfecto con esto puedo generar funciones simples a la medida del proyecto que estemos desarrollando, de manera de evitar que se repitan operaciones a lo largo del proyecto.

Define que una interfaz se va a usar como una función