Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Función: Transformación de Datos | Section
Stream API en Java

bookFunción: Transformación de Datos

Desliza para mostrar el menú

Mientras que Predicate nos ayuda a evaluar expresiones booleanas, Function nos permite transformar datos aplicando operaciones que devuelven resultados basados en la entrada.

Function se utiliza comúnmente para la transformación de datos, como la conversión de tipos, cálculos o procesamiento de valores.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

La interfaz Function<T, R> en Java representa una interfaz funcional que recibe un argumento de tipo T y devuelve un resultado de tipo R.

El método apply(T t) realiza la transformación de datos tomando el valor de entrada y devolviendo el resultado. Esto permite crear funciones flexibles para procesar datos de diversos tipos.

Aplicación práctica

Suponga que tiene una lista de nombres de usuario y necesita calcular la longitud de cada nombre para su posterior análisis o procesamiento de datos.

Main.java

Main.java

copy
1234567891011121314151617
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> users = Arrays.asList("Alice", "Bob", "Charlie", "David"); Function<String, Integer> nameLength = name -> name.length(); users.forEach(user -> { System.out.println(user + " has " + nameLength.apply(user) + " characters."); }); } }

En este ejemplo, tienes una lista de nombres de usuario. Para cada nombre, utilizas la función nameLength, que calcula el número de caracteres en el nombre usando el método length(). Utilizando el método forEach, iteras sobre cada elemento de la lista y muestras un mensaje indicando cuántos caracteres contiene cada nombre.

Combinación de funciones

La interfaz Function proporciona varios métodos para la combinación de funciones, lo que permite crear una cadena de operaciones.

Método andThen()

El método andThen() permite combinar dos funciones aplicando primero una función y luego pasando el resultado a la segunda función. Esto es útil cuando se necesita realizar múltiples operaciones en secuencia.

Ejemplo

Se dispone de una lista de nombres de usuario, y se requiere capitalizar la primera letra de cada nombre y luego verificar si el nombre tiene más de 5 caracteres.

Main.java

Main.java

copy
1234567891011121314151617181920212223
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("john", "alice", "bob", "charlie", "david"); // Capitalize first letter Function<String, String> capitalizeFirstLetter = name -> name.substring(0, 1).toUpperCase() + name.substring(1); // Check if the username has more than 5 characters Function<String, Boolean> isLongerThanFive = name -> name.length() > 5; // Combine functions using `andThen()` Function<String, Boolean> formattedNameThenCheckLength = capitalizeFirstLetter.andThen(isLongerThanFive); usernames.forEach(user -> { System.out.println(user + " -> " + formattedNameThenCheckLength.apply(user)); }); } }

Primero se capitaliza la primera letra de cada nombre de usuario utilizando capitalizeFirstLetter. Luego, se verifica si el nombre formateado tiene más de 5 caracteres usando isLongerThanFive. Las dos funciones se combinan utilizando andThen() para un procesamiento secuencial.

Método compose()

El método compose() permite combinar funciones, pero en orden inverso: la segunda función se aplica primero, y el resultado se pasa luego a la primera función.

Ejemplo

Se dispone de una cadena de texto y se desea primero calcular su longitud y luego añadir un prefijo al resultado.

Main.java

Main.java

copy
123456789101112131415161718
package com.example; import java.util.function.Function; public class Main { public static void main(String[] args) { String phrase = "Hello World"; // First, calculate the length, then add a prefix Function<String, Integer> stringLength = String::length; Function<Integer, String> addPrefix = length -> "Length: " + length; // Combine functions using compose Function<String, String> lengthThenPrefix = addPrefix.compose(stringLength); System.out.println(lengthThenPrefix.apply(phrase)); // Output: Length: 11 } }

En este ejemplo, primero se calcula la longitud de la cadena utilizando stringLength, y luego el resultado se pasa a la función addPrefix, que antepone un prefijo. Se utiliza compose() para aplicar las funciones en el orden deseado.

Método identity()

El método identity() devuelve una función que simplemente retorna su argumento sin ninguna modificación. Esto es útil cuando se necesita pasar una función que no altera el valor de entrada pero es requerida para cumplir con la interfaz.

Ejemplo

Suponga que se necesita procesar una lista de nombres de usuario aplicando varias transformaciones: una para convertir los nombres a mayúsculas, otra para agregar el sufijo "User", y una tercera utilizando la función identity() para dejar el nombre sin cambios. El objetivo es aplicar estas funciones a cada nombre en la lista manteniendo la interfaz del programa consistente para cada transformación.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132
package com.example; import java.util.List; import java.util.Arrays; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("alice", "bob", "charlie", "david", "eve"); // `Function` to convert the username to uppercase Function<String, String> uppercaseFunction = name -> name.toUpperCase(); // `Function` to add the "User" suffix Function<String, String> suffixFunction = name -> name + "User"; // Identity `Function`, which does nothing Function<String, String> identityFunction = Function.identity(); // Applying a combination of functions List<Function<String, ?>> transformations = Arrays.asList(uppercaseFunction, suffixFunction, identityFunction); // Applying each `Function` from the list for (Function<String, ?> transformation : transformations) { System.out.println("--------------------"); usernames.stream() .map(name -> transformation.apply(name)) .forEach(System.out::println); } } }

Como puedes ver, la salida consiste en tres listas formateadas de nombres de usuario. La última lista contiene los nombres originales, que es donde el método identity() resulta útil, ya que nos permite devolver los nombres sin agregar lógica adicional para manejar los valores sin cambios. Esto hace que el código sea más limpio y eficiente al usar directamente identity() cuando no se necesita transformación.

1. ¿Qué hace el método andThen() en la interfaz Function?

2. ¿Cuál será el resultado al aplicar el método identity()?

3. ¿Qué hace el método compose()?

question mark

¿Qué hace el método andThen() en la interfaz Function?

Select the correct answer

question mark

¿Cuál será el resultado al aplicar el método identity()?

Select the correct answer

question mark

¿Qué hace el método compose()?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 1. 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

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