Bienvenidos.
Veamos el happy stream de Yaba.
Bueno, creo que es una combinación de las mejores ideas que tiene el literato y la programación funcional
para implementar flujos de datos.
Podemos definir como una secuencia de elementos que provienen de una fuente, una fuente de dato típicamente
de una lista o una colección de yaba, ya sea un set, un list bueno, cualquiera que implemente la
interfaz colectaron o un arreglo una matriz.
Claro, también puedo convertir un arreglo común y corriente de Java directamente en un stream y que
estos pasen por una especie de tubería.
Filtros se pueden modificar los elementos, podemos ir y dando effi la idea poder realizar operaciones
que se le conoce como operadores que son aplicado a cada uno de estos elementos que se van emitiendo,
que van fluyendo en este flujo de datos.
En esta secuencia bueno, como alegoría es como una tubería de agua, una corriente.
De ahí viene el término stream de corriente o flujo.
El orden que mantiene los elementos es el mismo que la fuente, es el mismo que mantiene el list@,
por ejemplo, la lista o el arreglo.
Pero un tema importante que hay que tener en cuenta los stream nos sirven para almacenar datos, no
son contenedores.
Almacenamos, por ejemplo, en un arreglo, en una lista.
Simplemente esto es como una conducción para poder realizar un trabajo sobre los elementos de esta fuente.
Entonces, un flujo no es una estructura de datos que almacena elementos, no es como Lalit las colecciones
no en su lugar transmite esto elementos de una fuente como un generador o un canal de entrada y salida
a través de esa tubería con operaciones computacionales.
Esa la idea.
Veamos las características más importante.
Entonces permite crear flujo de datos continuos que contienen operadores para procesar una secuencia.
Elementos Los operadores reducen notablemente las tareas de transformación de este flujo de este elemento.
Después vamos a ver que podemos convertir, por ejemplo, un flujo de un tipo dato en un flujo de otro
tipo dato o bien mantener el mismo tipo de datos, pero convertir la información por ejemplo a mayúscula
minúscula, concatenar, agregar más información, obtener el máximo, el mínimo, contar elementos,
sumar en caso de que sean numéricos, aplicar el operador por ejemplo distinto para no tener elementos
repetidos y los repetidos se agrupan en uno solo.
En fin, entonces se transforma y compone flujo con los operadores map que es para manipular modificar
filter para filtrar concatenar con con cat el flat map sort para ordenar for each para iterar y mostrar
los elementos para hacer algo redux para realizar una operación matemática, por ejemplo, o algún algoritmo
de todos los elementos y finalmente convertirlos en uno solo.
Y pueden ser creados desde cualquier estructura dato, desde una lista, un set, cualquier tipo collection,
pero también arreglos y también rangos.
Otra característica es la inmutabilidad.
Esto significa que una instancia de cualquiera de ellos, de cualquier stream, no se puede modificar
en absoluto.
Sin embargo, cada vez que llamamos a un operador, por ejemplo, el map filter, que en realidad sí
modifica la forma en que se representan los datos, pero no estamos modificando el objeto original como
tal.
No hay que tengo modificando el stream original, sino que cada vez que invocamos estos métodos se crea
una nueva instancia de un stream nuevo.
Con estos cambios y se deja la instancia original de flujo completamente intacta e inmutable, de tal
forma que en cualquier momento podemos recuperar.
Podemos volver al estado original que tenía antes.
Entonces el map, el filter y cualquier operador retornan una nueva instancia del stream, no alterando,
no modificando el stream original.
Otra característica en la concurrencia hechos simple los stream nos permiten abstraer y simplificar
bastante todo lo que concurrencia sincronización.
Todo lo que detalle de bajo nivel de los Dredd.
Los hilos.
Podríamos tener múltiples tareas o procesamientos que se están ejecutando mismo tiempo y todos estos
detalles problemas de bajo nivel se facilitan bastante de forma automática con el manejo de concurrencia.
Ya vienen implementado en los extremos.
Trabaja con flujo de datos continuos.
Por ejemplo, acá tenemos un flujo de 9 elementos.
Podríamos pensar o representar un stream como una línea de San Plage donde los elementos del flujo fluyen
a través de una cinta transportadora.
Por ejemplo, nuestra materia prima.
Los elementos del flujo se van a mover a través de esta cinta para ser procesados con estaciones de
trabajo donde captación de trabajo podría manipular estos elementos, convertirlos, filtrarlos, trabajar
con ellos y otros pasos intermedios.
Estas transformaciones irían a través de los operadores que convierten, transforman el flujo y finalmente
termina como un producto final listo para ser enviado al consumidor.
Los operadores reducen notablemente las tareas de transformaciones menos en más.
Podemos hacer muchas cosas en unas pocas líneas de código.
Por ejemplo.
Tenemos el operador MAP.
De hecho, estamos utilizando una prisión Lanta.
Bueno, y prácticamente toda la implementación del API Stream está basada en operadores que trabaja
con expresiones lambda, las que vimos en el caso del MAP con un Phantom, una función que pasa por
argument un valor y devuelve este valor modificado.
Acá podemos obtener este elemento que se emite y le podemos hacer o realizar alguna aplicación, alguna
modificación.
Por ejemplo, este valor multiplicarlo por 10 donde X es un número.
O bien si tenemos un flujo que contiene un tipo usuario y el usuario tener varios atributos por ejemplo
nombre, apellido o el email.
Pero solamente nos interesa extraer el email nada más el email de cada usuario.
Pero perfecto.
Podríamos convertir con el MAP este flujo del tipo usuario a un flujo del tipo string que solamente
contenga el email.
Entonces finalmente regresaría un stream con todos los email de los usuarios y después podemos convertir
este stream a otra lista con los datos procesados.
Es decir, finalmente convertimos o traspasamos una lista de usuario a una lista de email del tipo String.
Otro operador muy importante es el filter para filtrar.
Por ejemplo, acá tenemos un flujo que contiene números, pero quiero filtrar solamente los que sean
mayores que 10 y todo lo que sean menores que 10 no los vamos a procesar.
Por lo tanto, que haríamos con el 30, con el 22 y con el 60?
Luego trabajamos con ese subconjunto del stream original y así tenemos muchos operadores más para trabajar
que los veremos durante esta sección.
Nada más nos vemos en la siguiente clase.