Skip to content

Commit 2ec4b48

Browse files
committed
Ejemplos de referencia de metodos
1 parent 5578aba commit 2ec4b48

1 file changed

Lines changed: 123 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.platzi.functional._16_listeners;
2+
3+
import com.platzi.functional.util.Utils;
4+
5+
import java.util.List;
6+
import java.util.concurrent.atomic.AtomicInteger;
7+
import java.util.stream.Stream;
8+
9+
public class StreamListeners {
10+
static void listeners() {
11+
/*
12+
Mencionamos que los Streams son "auto iterables"
13+
Entonces… como podemos obtener los datos para procesarlos?
14+
15+
Es facil, la clase Stream tiene un API funcional que nos permite pasar Suppliers, Consumers,
16+
Predicates, etc. Lambdas a final de cuentas.
17+
*/
18+
Stream<String> coursesStream = Stream.of("Java", "Functional");
19+
coursesStream.forEach(course -> System.out.println("Curso de platzi sobre: " + course));
20+
21+
/*
22+
A estas lambdas o funciones que agregamos para procesar los streams, se les conoce como listeners.
23+
24+
Aunque este nombre/definicion depende del autor, tiene mucho sentido llamarles asi,
25+
pues el Stream se empezara a iterar una vez que encuentre el set de datos y las operaciones
26+
a aplicar e ira invocando a cada una de estas operaciones con los valores correspondientes.
27+
*/
28+
29+
/*
30+
Hay diferentes tipos de operaciones que aceptan diferentes tipos de listeners, por ejemplo,
31+
el filtrado de datos:
32+
*/
33+
AtomicInteger x = new AtomicInteger();
34+
Stream<Integer> countingStream = Stream.generate(() -> x.getAndIncrement());
35+
36+
//Filtramos los datos para tener solo los numeros pares producidos por el stream
37+
countingStream.filter(i -> i % 2 == 0);
38+
39+
//O elevamos cada numero al cuadrado…
40+
countingStream.map(i -> i * i);
41+
42+
//
43+
//
44+
//
45+
//
46+
47+
/*
48+
Una situacion que se presenta en muchas ocasiones es tener un Stream<List<String>> donde
49+
tenemos un Stream que emite colecciones.
50+
Si intentamos operar sobre estre Stream no podremos acceder a los Strings de cada lista,
51+
solo a las listas como tal… operar de vuelta la lista no es una opcion si estamos haciendo
52+
cosas en paralelo.
53+
*/
54+
Stream<List<String>> coursesModules = Stream.of(/*Obentemos los cursos de una DB*/);
55+
//Nos devuelve un Stream de List<String> donde las listas tienen literalmente el elemento "Java"
56+
//Tal vez nuestra busqueda era sobre cursos que contuvieran la palabra Java como parte del nombre…
57+
coursesModules.filter(s -> s.contains("Java"));
58+
59+
/*
60+
Para poder operar este tipo de streams, usaremos una operacion llamada flatMap
61+
62+
flatMap toma un Stream<Collecion<T>> y nos devuelve un Stream<T>.
63+
64+
Es decir, flatMap se encarga de combianr todos los elementos de las colecciones de los streams
65+
en un solo Stream. Para hacer esto, debemos proveer una lambda que emita un stream como resultado
66+
67+
Si nuestro Stream inicial tenia:
68+
Stream{ List{ "Node.js", "JavaScript"}, List{"Android", "Kotlin"}, List{"JavaSE 8", "Java FP"}}
69+
70+
Aplicar flatMap devuelve:
71+
Stream{ "Node.js", "JavaScript", "Android", "Kotlin", "JavaSE 8", "Java FP" }
72+
*/
73+
List<String> nodeCourses = Utils.getListOf("Node.js", "Express.js", "Eventloop");
74+
List<String> javaCourses = Utils.getListOf("Spring", "Maven", "Gradle", "Funtional");
75+
76+
Stream<List<String>> courses = Stream.of(nodeCourses, javaCourses);
77+
78+
//Sin flatMap
79+
long jsCourses = courses.filter(course -> course.contains("js")).count();
80+
System.out.println(jsCourses); // 0
81+
82+
jsCourses = courses.flatMap(list -> list.stream()) //Tambien Collection::stream es valido
83+
.filter(course -> course.contains("js"))
84+
.count(); // 2 (Node.js, Express.js)
85+
86+
//
87+
//
88+
//
89+
//
90+
//
91+
/*
92+
Hablamos un poco sobre como crear streams desde una funcion y que estos streams pueden
93+
emitir datos invocando a esta funcion.
94+
95+
Sin embargo… que los detiene? Estos streams son infinitos, para detenerlos podemos utilizar `limit`
96+
*/
97+
Stream<Integer> firstTen = Stream.iterate(0, i -> i + 1);
98+
firstTen.limit(10)
99+
.forEach(System.out::println);
100+
101+
102+
103+
104+
/*
105+
Tambien es posible que usemos objetos en lugar de lambdas. Recordemos que al final las lambdas
106+
son funciones y los metodos son funciones. Podemos usar objetos siempre que sus
107+
metodos cumplan con la necesidad de tener los parametros correctos y devolver el tipo correcto.
108+
*/
109+
NumericOperator numericOperator = new NumericOperator();
110+
Stream<Integer> numbers = Stream.iterate(0, numericOperator::operate);
111+
firstTen.limit(10)
112+
.forEach(System.out::println);
113+
}
114+
//
115+
//
116+
//
117+
//
118+
static class NumericOperator {
119+
public int operate(int x) {
120+
return x + 3;
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)