Skip to content

mejoras al projecto original #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 115 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
b2b7d8f
Ejemplo de funcion pura agregado
sierisimo Dec 12, 2019
b577b6c
Agregando ejemplo de side effects
sierisimo Dec 12, 2019
6dee3d2
Ejemplos de mutabilidad en java
sierisimo Dec 12, 2019
79f378b
Ejemplo practico de funciones en Java
sierisimo Dec 12, 2019
0ac36f5
Ejemplos de uso de las interfaces en java.util.function
sierisimo Dec 12, 2019
cd03cb8
Tema de SAM agregado
sierisimo Dec 12, 2019
fb6c2e3
Ejemplos del operador ::
sierisimo Dec 13, 2019
61ebd8c
Pequenio ejemplo de inferencia de tipos
sierisimo Dec 13, 2019
793385f
Sintaxis de lambdas con comentarios
sierisimo Dec 13, 2019
10b0f48
Las interfaces con metodos default son algo nuevo en java 8
sierisimo Dec 13, 2019
60f95b1
Metodos default con pequenos ejemplos
sierisimo Dec 13, 2019
8d40e4e
Chaining ejemplos con builders y funciones
sierisimo Dec 13, 2019
8a6fe70
Composition con ejemplos para compose y andThen
sierisimo Dec 13, 2019
5ca101a
Ejemplos iniciales sin comentarios
sierisimo Dec 13, 2019
acfc14e
Agregando ejercicio de composicion
sierisimo Dec 13, 2019
9330302
Merge branch '11-composicion-funcional' into 12-currying
sierisimo Dec 13, 2019
83c955e
Currying con comentarios. Dificil concepto, espero que el ejemplo ayu…
sierisimo Dec 14, 2019
4190575
Partial application example
sierisimo Dec 14, 2019
7d143b7
Explicaciones de optionals
sierisimo Dec 15, 2019
54a22d7
Agregando espacios para legibilidad
sierisimo Dec 15, 2019
d938c94
Ejemplo de throw desde optional
sierisimo Dec 15, 2019
b1b8b43
Arreglado error en ejercicios, actualizando datos de streams
sierisimo Dec 15, 2019
5578aba
Agregados comentarios
sierisimo Dec 15, 2019
2ec4b48
Ejemplos de referencia de metodos
sierisimo Dec 16, 2019
25ee996
Explicacion de operaciones y collectors
sierisimo Dec 16, 2019
27fec99
Definicion de operadores intermedios agregada
sierisimo Dec 16, 2019
bdba81f
Operaciones finales con ejemplos
sierisimo Dec 16, 2019
c534f1c
Archivos base para nuestro proyecto
sierisimo Dec 16, 2019
46853e1
Quitando librerias para el siguiente modulo
sierisimo Dec 16, 2019
3b86127
Agregando librerias
sierisimo Dec 16, 2019
40adc4b
README con opciones y ejemplos
sierisimo Dec 16, 2019
916c1e1
Funciones para crear objetos agregadas
sierisimo Dec 16, 2019
4b88119
Funciones de transformacion y ejecucion final
sierisimo Dec 16, 2019
882e2ca
Ejemplo de Math functions
sierisimo Dec 17, 2019
2a44936
CLIArguments y ejemplo de Consumer / Supplier
sierisimo Dec 17, 2019
96e33d8
BiFunction examples
sierisimo Dec 17, 2019
6116083
Ejemplo de FunctionalInterface
sierisimo Dec 17, 2019
870bf77
Referencias referencias y mas referencias
sierisimo Dec 17, 2019
dd8013b
Ejemplo directo con referencia a metodos
sierisimo Dec 17, 2019
8f50e8e
Merge branch '04-funciones-en-java' into ejemplos-en-clase
sierisimo Dec 17, 2019
028f425
Merge branch '05-Single-Abstract-Method-SAM' into ejemplos-en-clase
sierisimo Dec 17, 2019
8d3ed9a
quitando ejemplos no vistos en clase
sierisimo Dec 17, 2019
1ab2f05
Elminando ejemplos fuera de clase
sierisimo Dec 17, 2019
c4749a5
quitando ejemplos no vistos en clase
sierisimo Dec 17, 2019
7cc5bed
Merge branch '07-inferencia-de-tipos' into ejemplos-en-clase
sierisimo Dec 17, 2019
aa5dcc4
Ejemplo no usado, removido
sierisimo Dec 17, 2019
933732b
Ejemplo de inferencia de tipos
sierisimo Dec 17, 2019
93b5b27
Ejemplo de inferencia de tipos visto en clase
sierisimo Dec 17, 2019
04c030d
usos y sintaxis para lambdas
sierisimo Dec 17, 2019
899bbdb
Merge branch '09-metodos-default' into ejemplos-en-clase
sierisimo Dec 17, 2019
92ed1c8
Borrado de ejemplo no usado
sierisimo Dec 17, 2019
7672660
Ejemplo de metodos default
sierisimo Dec 17, 2019
9592c24
Merge branch '10-chaining' into ejemplos-en-clase
sierisimo Dec 17, 2019
cb94352
Ejemplos no usados en clase, borrados
sierisimo Dec 17, 2019
daa33b3
Chaining y chainer
sierisimo Dec 17, 2019
f392f85
Merge branch '11-composicion-funcional' into ejemplos-en-clase
sierisimo Dec 17, 2019
02682dc
Quitado composicion ejemplificado pero no de clase
sierisimo Dec 17, 2019
57e08a6
Agregando el ejemplo para operaciones
sierisimo Dec 17, 2019
4e152f5
Merge branch '14-optionals' into ejemplos-en-clase
sierisimo Dec 18, 2019
f1a0005
Quitando ejemplos no mostrados en clase
sierisimo Dec 18, 2019
5f0fc47
ejemplos con la clase optional mostrados en clase
sierisimo Dec 18, 2019
68a7939
Ejemplo de IntStream con paralelismo
sierisimo Dec 18, 2019
39c4539
Usando Collectors para convertir Streams
sierisimo Dec 18, 2019
668dbf7
first commit on course platzi java functional programing
MartinFiorde Jun 22, 2024
5411e82
Revert "quitando ejemplos no vistos en clase"
MartinFiorde Jun 22, 2024
6b85fca
Revert "Elminando ejemplos fuera de clase"
MartinFiorde Jun 22, 2024
75183f0
Revert "quitando ejemplos no vistos en clase"
MartinFiorde Jun 22, 2024
8a94f83
Revert "Ejemplo no usado, removido"
MartinFiorde Jun 22, 2024
a174470
Revert "Borrado de ejemplo no usado"
MartinFiorde Jun 22, 2024
3fa3891
rename to avoid conflict on revert
MartinFiorde Jun 22, 2024
8d6af0b
Revert "Ejemplos no usados en clase, borrados"
MartinFiorde Jun 22, 2024
d78b609
Revert "Quitado composicion ejemplificado pero no de clase"
MartinFiorde Jun 22, 2024
8fbad39
Revert "Quitando ejemplos no mostrados en clase"
MartinFiorde Jun 22, 2024
c4a83fd
Merge branch 'job-search' of https://github.com/MartinFiorde/platzi-j…
MartinFiorde Jun 22, 2024
3f8524f
change package "functional" to "functional_teacher_theory"
MartinFiorde Jun 22, 2024
c2674d6
add package "functional_student_practice" to start class 11 practice
MartinFiorde Jun 22, 2024
e0b2606
Merge pull request #1 from MartinFiorde/refactor/starting-point
MartinFiorde Jun 22, 2024
7934f1a
Merge pull request #2 from MartinFiorde/main-fork
MartinFiorde Jun 22, 2024
840235c
class 11
MartinFiorde Jun 22, 2024
3182c62
class 12 lambdas y Predicate
MartinFiorde Jun 22, 2024
2561ef2
class 13 consumers and suppliers
MartinFiorde Jun 22, 2024
d1dba30
implemented supplier and consumer
MartinFiorde Jun 22, 2024
d874c80
class 14 BiFunction and BinaryOperator
MartinFiorde Jun 22, 2024
87ff996
class 15 sam and FunctionalInterface
MartinFiorde Jun 23, 2024
cae537b
class 8 inmutable and update to java17 for tests with List.of()
MartinFiorde Jun 25, 2024
9a5f76d
class 8 improve doc
MartinFiorde Jun 25, 2024
30ab6c8
class 16 reference operator "::"
MartinFiorde Jun 25, 2024
3eb4015
fix linter
MartinFiorde Jun 25, 2024
ef6d8a2
update gradle version
MartinFiorde Jun 28, 2024
b7ea30c
added study docs
MartinFiorde Jun 28, 2024
fdf50b5
class 17 inference
MartinFiorde Jun 28, 2024
d04ad7d
fix
MartinFiorde Jun 28, 2024
442c370
final fix. proyect compatible with java21
MartinFiorde Jun 28, 2024
d774b40
fix linter
MartinFiorde Jun 28, 2024
aec0ecb
fix and unified build.gradle files
MartinFiorde Jun 28, 2024
e3e5b58
fix
MartinFiorde Jun 28, 2024
fa947b2
class 18 lambda syntax
MartinFiorde Jun 29, 2024
dce25e9
fix on examples, updated dependencies versions
MartinFiorde Jun 29, 2024
82a97e1
class 19 default methods in interfaces
MartinFiorde Jun 29, 2024
507a4e4
class 20 chaining
MartinFiorde Jul 2, 2024
bd42aa7
class 21 composition
MartinFiorde Jul 2, 2024
bd25b45
change folder name
MartinFiorde Jul 4, 2024
0ce882c
class 21 theory improved
MartinFiorde Jul 23, 2024
fba7470
refactor file name changes
MartinFiorde Jul 23, 2024
f35f34f
class 22 Optional
MartinFiorde Jul 23, 2024
4e0d379
class 23 24 streams
MartinFiorde Jul 24, 2024
e1fb8d5
class 26 29 Streams advanced methods
MartinFiorde Jul 24, 2024
214c2e3
class 25 27 28 Streams theory
MartinFiorde Jul 24, 2024
5a03ed7
Merge pull request #3 from MartinFiorde/maf-practice
MartinFiorde Jul 24, 2024
b768f15
Merge pull request #4 from MartinFiorde/main-fork
MartinFiorde Jul 24, 2024
5436cee
class 30-40 JobSearchReporter
MartinFiorde Jul 24, 2024
ea5855a
mejoras varias
MartinFiorde Jul 24, 2024
d5e952c
Merge pull request #5 from MartinFiorde/maf-practice
MartinFiorde Jul 24, 2024
e7b21a3
Clear of personal practice. Keep global config for java 21 and better…
MartinFiorde Jul 24, 2024
2430990
Merge pull request #6 from MartinFiorde/refactor/clean-personal-practice
MartinFiorde Jul 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
class 25 27 28 Streams theory
  • Loading branch information
MartinFiorde committed Jul 24, 2024
commit 214c2e3f0d39b4c2416d00180ed8ef09e11aeeba
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package com.platzi.functional_student_practice._15_streams;

import com.platzi.functional_teacher_theory.util.Utils;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class C25CollectorsTheory {

/*

Operaciones y Collectors

Usando Stream nos podemos simplificar algunas operaciones, como es el filtrado, el mapeo,
conversiones y más. Sin embargo, no es del tod0 claro cuándo una operación nos devuelve otro
Stream para trabajar y cuándo nos da un resultado final…

¡O al menos no era claro hasta ahora!

Cuando hablamos de pasar lambdas a una operación de Stream, en realidad, estamos delegando a
Java la creación de un objecto basado en una interfaz.

Por ejemplo:

*/

public static void main(String[] args) {

Stream<String> coursesStream = Utils.getListOf("Java", "Node.js", "Kotlin").stream();
List<String> javaCoursesStream = coursesStream.filter(course -> course.contains("Java")).toList();

// En realidad, es lo mismo que:
List<String> explicitOperationStream = coursesStream.filter(new Predicate<String>() {
public boolean test(String st) {
return st.contains("Java");
}
}).toList();
}

/*

Estas interfaces las mencionamos en clases anteriores. Solo como repaso, listo algunas a
continuación:

Consumer<T>: recibe un dato de tipo T y no genera ningún resultado
Function<T,R>: toma un dato de tipo T y genera un resultado de tipo R
Predicate<T>: toma un dato de tipo T y evalúa si el dato cumple una condición
Supplier<T>: no recibe ningún dato, pero genera un dato de tipo T cada vez que es invocado
UnaryOperator<T> recibe un dato de tipo T y genera un resultado de tipo T

Estas interfaces (y otras más) sirven como la base de donde generar los objetos con las lambdas
que pasamos a los diferentes métodos de Stream. Cada una de ellas cumple esencialmente con
recibir el tipo de dato de el Stream y generar el tipo de retorno que el método espera.

Si tuvieras tu propia implementación de Stream, se vería similar al siguiente ejemplo:

public class PlatziStream<T> implements Stream {
private List<T> data;

public Stream<T> filter(Predicate<T> predicate) {
List<T> filteredData = new LinkedList<>();
for(T t : data){
if(predicate.test(t)){
filteredData.add(t);
}
}

return filteredData.stream();
}
}

Probablemente, tendría otros métodos y estructuras de datos, pero la parte que importa es justamente
cómo se usa el Predicate. Lo que hace Stream internamente es pasar cada dato por este objeto que
nosotros proveemos como una lambda y, según el resultado de la operación, decidir si debe incluirse
o no en el Stream resultante.

Como puedes notar, esto no tiene mucha complejidad, puesto que es algo que pudimos fácilmente replicar.
Pero Stream no solo incluye estas operaciones “triviales”, también incluye un montón de utilidades
para que la máquina virtual de Java pueda operar los elementos de un Stream de manera más rápida y
distribuida.



Operaciones

A estas funciones que reciben lambdas y se encargan de trabajar (operar) sobre los datos de un Stream
generalmente se les conoce como Operaciones.

Existen dos tipos de operaciones: intermedias y finales.

Cada operación aplicada a un Stream hace que el Stream original ya no sea usable para más operaciones.
Es importante recordar esto, pues tratar de agregar operaciones a un Stream que ya esta siendo
procesado es un error muy común.

En este punto seguramente te parezcan familiares todas estas operaciones, pues vienen en forma de
métodos de la interfaz Stream. Y es cierto. Aunque son métodos, se les considera operaciones,
puesto que su intención es operar el Stream y, posterior a su trabajo, el Stream no puede volver a
ser operado.

En clases posteriores hablaremos más a detalle sobre cómo identificar una operación terminal de una
operación intermedia.



Collectors

Una vez que has agregado operaciones a tu Stream de datos, lo más usual es que llegues a un punto
donde ya no puedas trabajar con un Stream y necesites enviar tus datos en otro formato, por ejemplo,
JSON o una List a base de datos.

Existe una interfaz única que combina todas las interfaces antes mencionadas y que tiene como única
utilidad proveer de una operación para obtener todos los elementos de un Stream: Collector.

Collector<T, A, R> es una interfaz que tomará datos de tipo T del Stream, un tipo de dato mutable A,
donde se iran agregando los elementos (mutable implica que podemos cambiar su contenido, como un
LinkedList), y generara un resultado de tipo R.

Suena complicado… y lo es. Por eso mismo, Java 8 incluye una serie de Collectors ya definidos para
no rompernos las cabeza con cómo convertir nuestros datos.

Veamos un ejemplo:

*/

public List<String> getJavaCourses(Stream<String> coursesStream) {
List<String> javaCourses = coursesStream
.filter(course -> course.contains("Java"))
.collect(Collectors.toList());
return javaCourses;
}

/*

Usando java.util.stream.Collectors podemos convertir muy sencillamente un Stream en un Set, Map,
List, Collection, etc. La clase Collectors ya cuenta con métodos para generar un Collector que
corresponda con el tipo de dato que tu Stream está usando. Incluso vale la pena resaltar que
Collectors puede generar un ConcurrentMap que puede ser de utilidad si requieres de multiples
threads.

Usar Collectors.toXXX es el proceso inverso de usar Collection.stream(). Esto hace que sea fácil
generar APIs publicas que trabajen con estructuras/colecciones comunes e internamente utilizar
Stream para agilizar las operaciones de nuestro lado.



Tipos de retorno

Hasta este punto, la única manera de obtener un dato que ya no sea un Stream es usando Collectors,
pues la mayoría de operaciones de Stream se enfocan en operar los datos del Stream y generar un
nuevo Stream con los resultados de la operación.

Sin embargo, algunas operaciones no cuentan con un retorno. Por ejemplo, forEach, que es una
operación que no genera ningún dato. Para poder entender qué hace cada operación basta con
plantear qué hace la operación para poder entender qué puede o no retornar.

Por ejemplo:

La operación de findAny trata de encontrar cualquier elemento que cumpla con la condición
del Predicate que le pasamos como parámetro. Sin embargo, la operación dice que se devuelve
un Optional. ¿Qué pasa cuando no encuentra ningún elemento? ¡Claro, por eso devuelve un
Optional! Porque podría haber casos en que ningún elemento del Stream cumpla la condición.

En las clases posteriores haremos un listado más a detalle y con explicaciones de qué tipos de
retorno tiene cada operación. Y entenderemos por qué se categorizan como operaciones finales e
intermedias.


Conclusiones

Por ahora, hemos entendido que cada operación en un Stream consume hasta agotar el Stream.
Y lo hace en un objeto no reusable. Esto implica que tenemos que decidir en nuestro código
cuándo un Stream es un elemento temporal para una función o cuándo realmente una función
sera la última en tocar los datos del Stream.

Las siguientes clases y lecturas cubrirán mas a detalle las múltiples operaciones y cómo
afectan a los datos del Stream.

*/
}
Loading