0. Programación Funcional - giovany79/reactive GitHub Wiki
Para entender la programación funcional, antes debemos entender los diferentes paradigmas o formas de programación. No hay un solo estilo de programación. Se puede decir que hay varios sabores de programación, donde algunos de ellos son soportados por los diversos lenguajes de programación. En el contexto de Java, este soporta dos estilos de programación los cuales son la programación imperativa y la programación declarativa.
Aquí están agrupados los principales lenguajes de programación. Se define en términos de instrucciones, condiciones, estructuras cíclicas y mutación de variables con el fin de llegar a un resultado. Le decimos al lenguaje de programación que queremos hacer y cómo lo queremos hacer.
Ejemplo:
- Ve por un vaso de agua.
- Camina 10 pasos
- abre la nevera
- estira la mano
- saca el agua
- cierra la nevera
- camina 10 pasos
Se define en términos de proposiciones y afirmaciones que son declaradas para describir el problema. Le decimos al lenguaje de programación que queremos hacer pero no como lo queremos hacer. En este tipo de programación no hay variables, no hay estructuras cíclicas, los datos son inmutables.
Ejemplo: Quiero un vaso de agua
Es una propiedad de los objetos cuyo estado no se puede cambiar una véz construido
Está basado en el paradigma de programación declarativa con el uso de funciones matemáticas. Tiene sus raíces en el cálculo lambda. Los programas basados en lenguaje funcional están constituidos únicamente por definiciones de funciones. Existen 2 tipos de lenguajes funcionales los cuales son los puros y los híbridos. Los puros tienen una mayor potencia expresiva conservando su transparencia referencial .Para Java se implementó a partir de la versión 8 del JDK.
Es una interfase que contiene exactamente un método abstracto y también contiene métodos por defecto y estáticos. También son conocidas como SAM (Single Abstract Method). Son ampliamente usadas en programación funcional
Vienen de las funciones matemáticas lambdas y son usadas por la programación funcional para simplificar su implementación. Normalmente se utilizan como:
- Argumentos que son pasados a otras funciones
- Para construir el resultado de una función superior
- Para contener funcionalidades que no necesitan ser nombradas También se conoce como funciones anónimas
-
Ej: (int x, int y) -> {return x + y;}
-
Los tipos pueden ser omitidos Ej: (x,y) -> {return x + y;}
-
Cuando el body contiene una sola expresión el return y las llaves pueden ser omitidas Ej: (x,y) -> {x + y}
-
Cuando la lista de parámetros tiene un solo valor, los paréntesis pueden ser omitidos Ej: value -> System.out.println("%d", value)
-
Cuando no se envían parámetros se crea los paréntesis con parámetros vacíos Ej: () -> System.out.println("Bienvenido a la programación funcional)
Los streams son objetos de clases que implementa la interfase stream (java.util.stream). Es principalmente usada para procesar colecciones de int, long o doubles o de objetos.
Mueve elementos a través de una secuencia de procesamiento de pasos que empieza con un datasource(array o colecciones) realiza varias operaciones intermedias en el datasource y finaliza con una operación terminal. Esta conformada por llamados a métodos encadenados. Una vez el stream es procesado no puede ser reusado porque no mantiene una copia del datasource original.
Especifica tareas a realizar en el stream donde siempre resultan en nuevos streams. Operaciones intermedias también se conocen como operaciones lazy, las cuales no son realizadas hasta que una operación final es invocada. Esto permite optimizar el performance del stream Ejemplo:
- Map
- FlatMap
- Filter
- Distinct
- Limit
- Sorted
Inicia el proceso de un stream pipeline de una operación intermedia y produce un resultado. Las operaciones terminales ejecutan el request cuando son llamadas Ejemplo:
- ForEach
- Average
- Count
- Max
- Min
- Reduce
- Collect
- ToArray
- FindFirst
- FirstAny
- AnyMatch
- AllMatch
Hace referencia a Stream compuestos por números enteros
Ejemplo: Imprime los números del 1 al 5
IntStream num = IntStream.of(1,2,3,4,5);
num.forEach(System.out::println)
Ejemplo: Genera números aleatorios del 1 al 10
IntStream it= IntStream.range(0, 10);
it.forEach(System.out::println);
Hace referencia a arrays de tipo integer
Ejemplo:
Integer[] values = {2, 9, 5, 0, 3, 7, 1, 4, 8, 6};
//Ordena el array de menor a mayor
System.out.printf("Sorted values: %s%n",
Arrays.stream(values)
.sorted()
.collect(Collectors.toList()));
Hace referencia a arrays de tipo String
String[] strings = {"Rojo", "Naranja", "Amarillo", "Verde", "Azul", "Violeta"};
// Pasa el string a mayusculas
System.out.printf("strings in uppercase: %s%n",
Arrays.stream(strings)
.map(String::toUpperCase);
.collect(Collectors.toList()));
Hace referencia a arrays de tipo Object
public class Employee{
private String firstName;
private String lastName;
private double salary;
private String department;
}
// initialize array of Employees
Employee[] employees = {
new Employee("Jason", "Rojo", 5000, "IT"),
new Employee("Ashley", "Verde", 7600, "IT"),
new Employee("Matthew", "Indigo", 3587.5, "Sales"),
new Employee("James", "Indigo", 4700.77, "Marketing"),
new Employee("Luke", "Indigo", 6200, "IT"),
new Employee("Jason", "Azul", 3200, "Sales"),
new Employee("Wendy", "Cafe", 4236.4, "Marketing")}; 25
List<Employee> list = Arrays.asList(employees);
System.out.println("Complete Employee list:");
list.stream()
.forEach(System.out::println);
// Retorna verdadero si el salario esta en el rango $4000-$6000
Predicate<Employee> fourToSix =
e -> (e.getSalary() >= 4000 && e.getSalary() <= 6000);
System.out.printf(
Empleados que ganan entre $4000-$6000 por mes ordenado por salario :%n");
list.stream()
.filter(fourToSix)
.sorted(Comparator.comparing(Employee::getSalary))
.forEach(System.out::println);
SecureRandom random = new SecureRandom();
System.out.printf("%-6s%s%n", "Face", "Frequency");
random.ints(6_000_000, 1, 7)
.boxed()
.collect(Collectors.groupingBy( Function.identity(),
Collectors.counting()))
.forEach((face, frequency) ->
System.out.printf("%-6d%d%n", face, frequency));
Function.identity()
- Libro How to Program Early Objects 10th Edition - Deitel y Deitel - Capitulo 17 - Streams