Java 8 fluencias, una introducción práctica | Jeronemo | Skillshare

Velocidad de reproducción


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Java 8 fluencias, una introducción práctica

teacher avatar Jeronemo

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Ve esta clase y miles más

Obtenga acceso ilimitado a todas las clases
Clases enseñadas por líderes de la industria y profesionales activos
Los temas incluyen ilustración, diseño, fotografía y más

Lecciones en esta clase

    • 1.

      Introducción

      0:41

    • 2.

      Stream uso y uso de caso

      3:28

    • 3.

      Interfaces funcionales y Lambda

      10:48

    • 4.

      Operaciones de transmisión

      1:52

    • 5.

      Operación intermedia: filtro

      1:19

    • 6.

      Operación de los terminales: para cada

      1:31

    • 7.

      Operación intermedia: mapa

      1:34

    • 8.

      Operación intermedia: flatMap

      2:36

    • 9.

      Operaciones Intermediate secuencial y paralelo

      2:48

    • 10.

      Operación intermedia: peek

      1:33

    • 11.

      Operación de los terminales: recogida

      4:06

    • 12.

      Operación de los terminales: reducción

      5:11

    • 13.

      Resumen y palabra posterior

      1:31

  • --
  • Nivel principiante
  • Nivel intermedio
  • Nivel avanzado
  • Todos los niveles

Generado por la comunidad

El nivel se determina según la opinión de la mayoría de los estudiantes que han dejado reseñas en esta clase. La recomendación del profesor o de la profesora se muestra hasta que se recopilen al menos 5 reseñas de estudiantes.

34

Estudiantes

--

Proyecto

Acerca de esta clase

Los flujos se introdujeron en Java 8, pero son tan relevantes en Java 11, Java 17 y todas las versiones venideras. Son un aspecto clave para convertirse en un mejor desarrolladores de Java.

Esta clase te enseñará todo lo que necesitas saber sobre los flujos de Java para empezar a usarlos en tus propios proyectos. Su objetivo es que puedas comprender las posibilidades de los arroyos, así como que puedas reconocer situaciones en las que los arroyos pueden ser útiles. Se centra principalmente en aquellos que tienen poca o ninguna experiencia con Streams y lambdas, pero también se puede usar como un curso de actualización en las operaciones más utilizadas y su uso.

Lo que aprenderás en este curso:

  • Cómo funcionan las clases anónimas, las interfaces funcionales y las lambdas
  • Cómo funcionan los flujos en general y por qué deberías usarlos.
  • Cómo funcionan las operaciones más utilizadas en un stream.

Los flujos son un paso en la programación funcional. Dominar los flujos hace que tu código se pueda como una historia, que a su vez lo hace más que puedas mantenerlo para ti y otros. Al final hay ejercicios para que se practique todo.

Para quién es el curso:

Cualquier desarrollador de Java interesado en los flujos o la programación funcional en general. Mientras que el título menciona Java 8 (que era su versión de introducción), es una gran habilidad para tener no importa en qué versión de Java trabajes. Se espera que tengas una comprensión básica de usar Java, como la compilación y ejecución de código, así como la extensión de las clases e implementación de interfaces.

Materiales necesarios para este curso:

No se necesitan materiales para seguir junto con este curso. Sin embargo, si quieres hacer los ejercicios al final, tendrás que tener instalado JDK 8 o superior. También es necesario editar y ejecutar los archivos .java. Esto podría ser tan simple como el bloc de notes, pero recomiendo usar un IDE como IntelliJ o Eclipse.That's
es todo!

Conoce a tu profesor(a)

Teacher Profile Image

Jeronemo

Profesor(a)

Hey there, welcome to my profile! I have the classical Dutch name Jeroen, but you may call me Jeronemo.

I've been a backend developer for the good part of a decade, dabbing mostly in microservice architecture using REST, Java & Spring Boot, but having worked with loads of other stuff like ADO, Docker, ELK stack, Eureka, Flyway, Gitlab, GWT, Hazelcast, Hibernate, Hoverfly, IntelliJ, Jackson, Jenkins, JIRA, JSON, Junit, Kubernetes, RabbitMQ, Maven, Mockito, Nexus, SOAP, Sonar, SQL, WDSL, XSD & Zuul.

Ver perfil completo

Habilidades relacionadas

Desarrollo Lenguajes de programación Java
Level: All Levels

Valoración de la clase

¿Se cumplieron las expectativas?
    ¡Superadas!
  • 0%
  • 0%
  • Un poco
  • 0%
  • No realmente
  • 0%

¿Por qué unirse a Skillshare?

Mira las galardonadas Skillshare Originals

Cada clase tiene lecciones cortas y proyectos prácticos

Tu membresía apoya a los profesores de Skillshare

Aprende desde cualquier lugar

Ve clases sobre la marcha con la aplicación de Skillshare. Progresa en línea o descarga las clases para verlas en el avión, el metro o donde sea que aprendas mejor.

Transcripciones

1. Introducción: Hola a todos, bienvenidos a la clase Java ocho streams, una introducción práctica. Mi nombre es jornero, y en esta clase te estaré contando todo sobre las transmisiones en su uso. Esta clase está dirigida a dosificar, tener poca o ninguna experiencia con arroyos es gasa para darte una idea la posibilidad de arroyos. Reconoces situaciones en las que las transmisiones pueden ser útiles. Profundizaremos en el uso de arroyos y ampliamente. Quieres utilizarlos en interfaces funcionales y lambdas. Voy a explicar las operaciones de uso común para aquellos ansias o enfoque más práctico. Este curso también ofrece ejercicios para poner en práctica los conocimientos aprendidos. Empecemos. 2. Stream uso y uso de estuches: Transmite el uso y el caso de uso. Las corrientes de agua utilizan para simplemente dicho, una corriente puede ser utilizada para procesar una colección de artículos. En un capítulo posterior, profundizaremos en algunas de las formas específicas de procesar una colección. Pero por ahora, solo piensa en procesar como filtrar, cambiar y enriquecer los datos para su recolección. Tenga en cuenta, sin embargo, las producciones utilizadas como entrada para las transmisiones en realidad no son cambiadas por las transmisiones. En cambio, ejecutar un stream nos da resultados separados desconectados de la colección original. Estos pasos de procesamiento de operaciones se escriben de manera funcionalmente descriptiva. decir, una transmisión se lee como una historia cuando se hace correctamente, que es lo que los hace tan increíblemente útiles. Para mostrar esto. Aquí hay un ejemplo de una forma convencional de filtrar, recopilar, clasificar e imprimir algunos datos. Yo uso la misma lógica escrita en arroyos. Si bien estoy seguro de que eventualmente podrás entender ambos lados, creo que todos podemos estar de acuerdo en que usar streams hace que sea mucho, mucho más fácil entender lo que hace el código. Entonces ahí lo tienes. Los streams se utilizan para procesar una colección de artículos de una manera muy razonable. ¿Cómo funcionan las transmisiones? Como se acaba de decir, los arroyos trabajan en una colección de artículos. Es posible que te hayas dado cuenta de que la colección de palabras coincide con una interfaz. En Java. interfaz que se encuentra en el paquete Java util es nuestro enlace para trabajar con streams. La mayoría de las veces, comúnmente usa una lista o un conjunto para iniciar una transmisión que extiende la interfaz de recopilación. Hay otras formas de crear una corriente. No vamos a entrar en ellos en esta clase. Los puedes encontrar en los recursos. Con la llegada de Java ocho, un método predeterminado llamado ha agregado un método predeterminado llamado stream a la interfaz de colección. Para aquellos que no estén familiarizados con los métodos predeterminados. Los métodos predeterminados le permiten agregar nuevas funcionalidades a las interfaces de sus bibliotecas y garantizar la compatibilidad binaria con el código escrito para versiones anteriores de las interfaces. Este método predeterminado stream devuelve una instancia del stream cuesta la clase API central que nos permite trabajar con ellos. Después de crear la transmisión, ahora puede encadenar operaciones juntas y ejecutar la transmisión. Más sobre esto más adelante. Resumamos lo que hemos aprendido hasta ahora. Los streams se utilizan para procesar una colección de elementos de una manera muy legible. Las transmisiones no cambian esta colección de fuentes, sino que crean un resultado separado desconectado de la colección original. La interfaz de flujo es el costo central de API de trabajar con streams. Cualquier cosa que extienda o implemente la interfaz de recopilación tiene un método de flujo predeterminado para interactuar con conjuntos de clase API central. 3. Interfaces funcionales y Lambda: Interfaces funcionales y lambdas. Antes de que podamos comenzar a hablar de operaciones de transmisión, tendremos que hablar sobre los requisitos previos usar tiras. Las lambdas. Las lambdas son básicamente clases internas anónimas, interfaces funcionales de las cuales el compilador Java implícito denota la información necesaria. Empecemos desde el principio. Clases internas anónimas. Al implementar una interfaz, vas a implementar todos sus métodos. Aquí hay un ejemplo en el que creas clase implementada y la instancias. Aquí tenemos una interfaz llamada mi interfaz con la impresión. Algo importante método es implementado por mi interfaz. Pero y si necesito una implementación ligeramente diferente de las impresiones, algo importante método. En este escenario, tendría que crear otra clase que implemente mi interfaz. Otra vez. Imagina que si tienes diez varianzas diferentes, pronto se volverá abarrotada real. Esa es una señal para clases internas anónimas. La clase interna anónima es una extensión de una clase. Una implementación de una interfaz sin nombre, de ahí anónima. Nos centraremos en la parte de interfaz S. Esa es la importante en el contexto de las corrientes. Como no tienen nombre, no podemos crear por sí sola una instancia de la clase interna anónima. En cambio, es necesario declarar e instanciar la clase interna anónima en una sola expresión. Esta expresión se ve de la siguiente manera, lo que se traduce a lo siguiente. Al crear la versión anónima de clase interna de mi interfaz info. Como puedes ver, hemos creado una instancia de mi interfaz sin necesidad una clase implementando la interfaz. Y si deseo agregar una nueva implementación de mi interfaz, simplemente puedo hacerlo. Ahí lo tenemos. Las clases internas anónimas se pueden usar para implementar una interfaz sin necesidad de definir una clase rígida. Simplemente puedes crearlos sobre la marcha. Interfaces funcionales. La interfaz funcional es solo una interfaz excepto que solo contiene un único método que debe implementarse. Cualquier interfaz que cumpla con ese criterio es una interfaz funcional. Al igual que nuestro ejemplo de mi interfaz hace un momento. Si bien no es necesario, puede agregar la anotación de interfaz funcional para mostrar su intención. Como un bono adicional, el compilador lanzará una excepción en tiempo de compilación cuando en realidad no es una interfaz funcional al usar esta anotación. Repasemos por las interfaces funcionales más comunes se utilizan cuando se trabaja con streams. Son primero uno es el proveedor con admitido consigue. No espera ningún argumento, pero sí devuelve algo. El proveedor le suministra algo, generalmente un objeto nuevo, vacío, limpio. Se podía ver como una fábrica. El siguiente es predicado. Con admitido. Espera un argumento, lo evalúa y devuelve un Booleano. Como su nombre lo indica, es básicamente una prueba. ¿El argumento t cumple con los criterios dados sí o no? consumidor con sus métodos acepta, acepta un argumento, hace algo con él, pero no devuelve nada, literalmente consumiendo los argumentos en el proceso. El consumidor de bicicletas hace lo mismo que consumidor, salvo que espera dos argumentos. Función con sus métodos aplican. Espera un argumento, t hace algo con él. Y las devoluciones en argumentos son básicamente mapear o enriquecer el argumento en el proceso, el argumento r y t pueden ser la misma clase. La función by hace lo mismo que la función. Exceptuados espera dos argumentos, T y U hacen algo con ellos. Soy devoluciones son igual que la función. Los argumentos pueden ser de la misma clase si es necesario. Y en esa nota, llegamos a la última interfaz funcional común. Operador binario. El operador binario es una extensión de por función donde T, U y R son exactamente la misma clase. Asegúrese de tener una comprensión decente de las interfaces funcionales en general y fuera de estas comunes antes de continuar. Ya que te ayudará a entender lambdas y las operaciones de stream más fácilmente. Expresiones lambda. La mayoría de nosotros más agrupados son clases internas anónimas de interfaces funcionales de las cuales el compilador Java conoce implícitamente la información necesaria. Ahora sabemos lo que es una clase interna anónima y cómo todavía necesitamos implementar todos los métodos de una interfaz. Observamos que las interfaces funcionales son interfaces regulares, excepto que solo tienen un único método que debe implementarse. Dado que una interfaz funcional solo tiene un método único, el compilador es capaz de entender mucha información basada en el contexto. Tú, como desarrollador puedes dejar fuera esa información. Entonces, deja saber al compilador que estás dejando las cosas fuera. Los problemas de sintaxis Lambda. Comenzaremos con una clase interna anónima irregular y convertiremos en una expresión lambda completa pieza por pieza. O use el predicado de la interfaz funcional para probar si un entero dado es mayor que uno. Cuidando el signo igual, notamos el nombre de la interfaz que estamos implementando. El cuerpo de la clase interna anónima, la firma del método y el cuerpo de los métodos que estamos implementando. Mire más de cerca el nombre de la interfaz y la firma del método. ¿Ves cómo el compilador podría inferir este conocimiento? Observe cómo los nombres de la interfaz ya están en el lado izquierdo de las declaraciones iguales. Observe cómo dado que el predicado es una interfaz funcional, solo hay un único método a implementar. Entonces ya sabemos qué métodos estamos implementando. Ambos tipos de información pueden ser inferidos por el compilador. Nuestro primer paso es escribir esto usando la sintaxis agrupada como, la flecha. Con él. Nos desharemos del nombre de la interfaz, nombre del método. Esto ya se ve mucho más limpio ¿verdad? Aquí vemos la entrada de los métodos, el entero en el lado izquierdo de la flecha, y el cuerpo del método en el lado derecho. Pero aún queda alguna información que podemos dejar fuera en este caso. Como hay un solo método y el compilador conoce la firma del mismo, el compilador puede inferir el tipo de entrada del contexto. Los corchetes alrededor de las entradas también han desaparecido. Esto sólo es posible porque es un solo parámetro. En caso de que tengas dos o más, los corchetes son obligatorios. Hay una cosa más que ahora podemos inferir. Tiene que ver con el cuerpo y la declaración de retorno. En el caso de tener una sola línea de código en el cuerpo del método, el compilador puede inferir que esa línea de código es de hecho la sentencia return del cuerpo. Con este paso final, hemos llegado a la expresión lambda en toda regla. Verás todo el tiempo cuando trabajas con cuerdas. En realidad, hay una manera de escribir la lambda aún más corta. En algunos casos. A esto se le llama referencia de método. Pero sugiero que lo busques tú mismo cuando tengas una buena comprensión de lo largo hace en general. Una última cosa importante a mencionar sobre nosotros agrupados es que las variables locales utilizadas en ellas deben ser finales o efectivamente finales. Efectivamente final significa una variable que no tiene la palabra clave final, pero su valor no cambia después de su primera asignación. La razón de esto es que agrupados somos básicamente una pieza de código que puedes ejecutar dentro de otros métodos. Como puede pasar nuestro predicado a una operación de filtro dentro de una cadena. Por esta razón, Java necesita crear una copia de la variable local para ser utilizada dentro de los pulmones. Para evitar problemas de concurrencia. El alfa ha decidido restringir por completo las variables locales. Resumamos lo que hemos aprendido hasta ahora. Las clases internas anónimas son clases internas que implementan una interfaz sin tener un nombre, sí necesitan ser declaradas e instanciadas que una vez. Las interfaces funcionales son regularmente interfaces excepto que las únicas contienen un único método que debe implementarse. La anotación de interfaz funcional se puede utilizar para hacer cumplir esta regla no es necesaria. Nos agrupan son clases internas anónimas de interfaces funcionales de las cuales el compilador Java puede inferir información faltante en función del contexto. Ahora sabemos cómo crear una expresión lambda y de clase interna anónima irregular. Y por último, las variables locales utilizadas en nosotros agrupados deben ser definitivas o efectivamente bien. 4. Operaciones de transmisión: En los próximos capítulos, voy a explicar las operaciones de uso común en cadenas. Pero primero, deberíamos hablar los dos tipos de operaciones posibles, las operaciones intermedias y terminales. Un flujo solo se ejecuta completamente cuando se usa una operación de terminal. Por lo tanto, una corriente siempre termina en una operación terminal y solo puede tener una de ellas en una corriente. Las operaciones intermedias son todas operaciones antes de llegar a la operación final de la terminal. Las operaciones intermedias devuelven una instancia de stream, lo que permite encadenarlas todas juntas. Dado que todas las operaciones intermedias devuelven flujo, puede almacenar una cadena sin operaciones de terminal en una variable. Gracias hoy, por lo que realmente puedes agregar pasos a tu stream en función de influencias externas, como un filtro diferente o una forma diferente de enriquecer los datos. Sin embargo, preste atención, aunque pueda almacenar operaciones intermedias en variables, no es posible ejecutar el mismo flujo dos veces con una operación de terminal. El compilador no reconoce esto, pero obtendrás una excepción como esta durante el tiempo de ejecución. Una vez más. Las operaciones intermedias devuelven un flujo y, por lo tanto, pueden vincularse y almacenarse en variables. Las operaciones intermedias por sí solas no ejecutan una transmisión. Una operación de terminal ejecuta el flujo completo y devuelve un valor que no sea un flujo. Un flujo solo se puede ejecutar una vez con una operación de terminal. Intentar hacerlo dos veces resulta en una excepción durante el tiempo de ejecución. Con este conocimiento, pasaremos a las operaciones de uso común. 5. Operación intermedia: filtro: Empecemos por lo básico. Filtro. El filtro es una operación intermedia que permite filtrar objetos de cadenas que no pasan la prueba dada. Se podría ver el filtro de operación intermedia como el equivalente de flujo de una sentencia if. entrada es un predicado que como aprendimos, recibe un objeto, realiza una prueba sobre él, devuelve verdadero o falso dependiendo de si pasó la prueba o no. He aquí un ejemplo de su uso. Y no te preocupes por las otras operaciones. Pronto llegaremos a esos. En este ejemplo, usamos filter para continuar la transmisión solo con objetos cuya lista de números de teléfono está vacía. Antes de regresar a los clientes restantes como una lista, filtrado se puede hacer usando cualquier valor final efectivo. Aquí, estamos filtrando en función de nuestra variable local, por ejemplo, también podemos encadenarlos usando múltiples filtros seguidos. La operación del filtro es un excelente ejemplo de cómo las transmisiones hacen que su código sea más legible. Especialmente si almacenaste mucho tiempo en un valor así. Ahora puedes ver lo que estamos filtrando de un vistazo. 6. Operación de terminales: para cada: Nuestra primera operación terminal para cada uno. El FOREach es una operación terminal muy sencilla. Se utiliza para realizar una determinada acción sobre todos los elementos de la corriente. Asumiendo los elementos en el proceso, sus insumos, es un consumidor. Entonces toma un objeto, hace algo con él, pero no devuelve ningún valor. Después. Hemos visto su implementación en la operación previamente discutida, pero aquí está una vez más. En este ejemplo, imprimimos el nombre de cada industria de clientes. Ten en cuenta que para cada uno solo operan sobre los elementos una vez que hayan pasado por el resto de la corriente. Entonces, si ponemos un filtro antes de la operación del terminal, así, entonces solo los clientes con menos de tres dispositivos obtienen su nombre de pila, imprímalo. Por último, ¿sabía que un método normal se puede utilizar en un agrupado también? Toma este método, por ejemplo ¿ no te parece eso una implementación de consumidor? Acepta un solo objeto, hace algo con él, pero no devuelve ningún valor después. Y de hecho, podemos usar este método en nuestro foreACH, haciéndolo más legible en el proceso. Y eso es todo. Para cada uno simplemente realiza una acción específica para cada elemento de la corriente que lo hace a través del resto de la corriente. 7. Operación intermedia: mapa: Otra operación intermedia básica, mapa. Map es una operación intermedia que se usa comúnmente para mapear de un tipo de objeto a otro. Pero normalmente también se utiliza para realizar lógica de negocios. Sus entradas es una función que como ahora sabemos, toma un objeto de clase a, hace algo con él, y devuelve un objeto de clase b donde las cláusulas a y B pueden ser la misma clase. Aquí hay un ejemplo donde mapeamos de la clase A a la B. Aquí tenemos un objeto cliente como entradas. Mapeamos eso a una cadena compuesta por su nombre y apellido antes de imprimirla. En este caso, estamos mapeando de la clase a a la clase B, del cliente a la cadena. En este siguiente ejemplo, tenemos un objeto cliente como entrada en el trabajo móvil a sus dispositivos. Luego devuelve el mismo objeto del cliente, enriqueciendo efectivamente tu propio objeto. En este caso, estamos mapeando de cliente a cliente y llegando al objeto en el camino. Tenga en cuenta que dado que el cuerpo de Lambda contiene dos declaraciones, tuve que agregar los corchetes y devolver la palabra clave de nuevo en. Finalmente, al igual que con cualquier operación intermedia, es posible tener múltiples operaciones matemáticas dentro de una misma corriente. 8. Operación intermedia: flatMap: A continuación, FlatMap. Como su nombre indica, FlatMap es similar a map. Se trata de una operación intermedia que se utiliza comúnmente para mapear de un tipo de objeto a otro. Con la diferencia de que FlatMap trabaja en relaciones uno a muchos. Su entrada también es una función, pero se impone una restricción al objeto de retorno. Se debe devolver una corriente. Aquí vemos el método firma de map y flatMap lado a lado para mostrarte la diferencia. Mientras que ambos esperan la función, flatMap espera que el valor r sea de tipo string. Echemos un vistazo a lo que hace y en qué se diferencia de eso. En nuestros ejemplos, hemos utilizado el objeto cliente, que tiene una lista de dispositivos. ¿Qué crees que pasaría si usáramos operación del mapa para convertir a cada cliente a sus dispositivos? Como puede ver en la salida, mapear de un cliente a una lista de dispositivos, da como resultado un flujo de listas de dispositivos. Cuando se imprimen, estas listas se imprimen una por una. Esto podría ser algo que necesites para tu caso de uso funcional. Pero la mayoría de las veces, te interesan todos los dispositivos separados en lugar de listas separadas de dispositivos. Aquí es donde entra FlatMap. Como se dijo antes. Flatmap impone una restricción en el objeto de retorno de la función. Se puede ver que la lambda ha cambiado ligeramente para FlatMap y ahora devuelve el dispositivo es un stream. En lugar de como lista. Observe en las salidas que los dispositivos ahora se imprimen uno por uno en lugar de lista por lista. La clave aquí es que FlatMap espera arroyos como resultados que luego se aplanan en una sola secuencia nuevamente. Una vez más juntos. Ahora puede ver claramente la diferencia entre el mapa y la operación FlatMap. Para resumir, los mapas deben usarse al convertir objetos con una relación uno a uno. Mientras que FlatMap debe usarse al convertir objetos con una relación de uno a muchos. Cuando se usa FlatMap, el valor de retorno es un flujo de objetos. 9. Operaciones intermedias: secuenciales y paralelas: Dos operaciones de una misma moneda, secuencial y paralela. Secuenciales y paralelas son ambas operaciones intermedias que hacen que el flujo completo secuencial o paralelo respectivamente. Dado que son operaciones intermedias, se pueden agregar a la transmisión juntas incluso varias veces. No importa en qué parte del arroyo se coloque la operación. Toda la corriente es secuencial o paralela. Ni un poco de ambos. tener en cuenta que la última operación secuencial o paralela mencionó la industria, la que realmente se utiliza. Eso quiere decir que esta corriente es exactamente la misma que esta corriente. Un flujo es secuencial por defecto, lo que significa que los elementos se ejecutan en el orden en que aparecen en la colección estadounidense. Eso también significa que estas corrientes tienen la misma salida. Como se puede ver. Esto da como resultado la impresión de uno a diez en orden con o sin la operación secuencial. Cuando cambiamos eso a paralelo, sin embargo, como puedes ver, obtenemos un resultado diferente cada vez que ejecutamos el Stream. Stream se ejecuta multi-hilo, lo que significa que el trabajo realizado se divide entre diferentes ejecutes. Las llamadas amenazas. Tenga en cuenta que hacer que una transmisión se ejecute en paralelo no significa automáticamente que la transmisión se pueda ejecutar a prueba de subprocesos. Tú, como desarrollador, tienes que asegurarte de que tu código funcione exactamente igual, 1236 o cualquier amenaza. Como no quiere. Otra cosa a tener en cuenta al ejecutar las cosas en paralelo es que no necesariamente significa que el trabajo se haga más rápido. Hacer algo multi-hilo significa que necesita dividir el trabajo en partes, crear un ejecutado para cada parte. Trabajo delegado, emergen los diferentes resultados en uno solo. Esto da como resultado algo de sobrecarga al ejecutar el código o stream, en nuestro caso, lo que solo será beneficioso si tienes suficientes elementos en tu stream o si tu stream es muy pesado de cómputo. Para resumir, las operaciones secuenciales y paralelas permiten hacer rápidamente todo el flujo secuencial o paralelo. ejecutar una transmisión paralela, usted, como desarrollador, tiene que asegurarse de que el código sea seguro para subprocesos. 10. Operación intermedia: peek: Vamos con uno simple antes de pasar a los complejos. Pq. Pq es una operación intermedia que literalmente te permite echar un vistazo detrás de escena al ejecutar una cadena. Su uso principal es la depuración y el registro de sus entradas. Como consumidor, es decir, recibe un valor y hace algo con él sin que haya un valor de retorno. Si bien es posible modificar los datos dentro de la operación pico, se arriesga al hacerlo. Dependiendo de su versión de Java y si su operación de terminal tiene o no su operación de terminal tiene necesidad de procesar los objetos en la cadena. El código dentro de peek puede o no ejecutarse. Tenga mucho cuidado al usar peak para cualquier cosa que no sea la depuración y el registro. He aquí un ejemplo de su uso. En este ejemplo, usamos peak para imprimir el nombre de un dispositivo antes de continuar mapeándolo a los detalles de su pedido, recopilando esos posibles procesamientos adicionales. Un resultado de esta transmisión es una lista de detalles del pedido. Gracias a la operación pico, podemos obtener algunos registros con un dispositivo que los objetos utilizan para los resultados. Y vi pico es simplemente una manera de conseguir algo de tala durante un arroyo. Puedes usarlo para modificar datos, pero es arriesgado, así que te desaconsejaría cuando aún no estés familiarizado con las transmisiones. 11. Operación de terminales: recolecta: Nuestra segunda operación terminal, recoger. Collect es una operación terminal que recoge todos los elementos de una corriente en algo. Se usa comúnmente para poner los elementos resultantes de una transmisión en una lista. Hay dos implementaciones para esta. El primero espera una implementación de la interfaz del colector. Sin embargo, esta no es una interfaz funcional y, por lo tanto, no se puede reescribir como una expresión lambda. Por suerte para nosotros, sí, Lava ha sido tan amable como para proporcionar a los colectores clústeres que contienen todo tipo de métodos útiles. Muchos están más allá del alcance de este taller. Pero hay uno que usarás frecuentemente coleccionistas puntean dos listas. Como cabría esperar. Esto devuelve una implementación de la interfaz recopiladora que recoge todos los elementos de la cadena en una lista y la devuelve. Yo personalmente uso este 190, 9% de las veces que necesito para recoger algo y espero que experimentes lo mismo. Pero para entender un poco mejor lo que hace, repasemos la segunda implementación. Este espera un proveedor y dos por consumidores. El doc de Java nos da una buena visión general de lo que hace. El proveedor nos suministra eso, lo que esperamos como resultado de la operación de recolección. Que el primer consumidor de bicicletas se utiliza para consumir un elemento de la corriente en estos resultados. Esto continúa hasta que todos los elementos de la corriente o consumidos en los resultados finales. Esto no nos muestra lo que hace el segundo consumidor bi en combinarlo, sin embargo, eso es porque el combinador solo es necesario cuando el stream se ejecuta en paralelo. En ese caso, es posible que tengas dos o más hilos comenzando con el proveedor. Después de que se hayan hecho todas las amenazas, resultados de esos hilos deben combinarse en un solo resultado, que es exactamente para lo que se utiliza un combinador. Pongámoslo en práctica. Usando un proveedor y dos por consumidores. Replicaré la recolección de los elementos del cliente en una transmisión. Empezaremos con el proveedor. Cuando las llamadas obtendrán la lista vacía donde pondremos todos los elementos de la corriente en. A continuación, necesitamos un consumidor de bicicletas que acumule todos los elementos de la cadena en la lista de suministros. Esto deja claro que nuestro resultado es efectivamente esa lista y que todos los elementos del cliente de la transmisión se acumulan en la lista de conjuntos. En caso de una corriente secuencial, ese será el final de la misma. Pero para permitir el procesamiento paralelo, se necesitará una final por consumidor que combine dos resultados en uno solo. Usando esto por consumidor, agregamos los elementos del segundo resultado al primero. Esto es repetido por la transmisión hasta que todos los resultados de las amenazas se fusionan de nuevo en uno. Aquí se llenan en la operación de recolección. Y con eso, ya sabes cómo personalizar tus propias colectas. Para reiterar, hay dos implementaciones de la cooperación colecta. El primero espera un recopilador del cual Java ha preparado algunas opciones para ti usando la cláusula colectores. El segundo espera un proveedor y que vincula a los consumidores, haciéndolo mucho más personalizable. Utilizarás la colección preparada de esta clase la mayor parte del tiempo. Pero al menos ahora ya sabes cómo funciona. 12. Operación de terminales: reduce: El operador final discutirá reducir. Reducir es una operación de terminal que se puede utilizar para reducir todos los elementos de un flujo en un solo objeto. Es un poco como cobrar operación que discutimos. Pero mientras que collect aplica todos los elementos de la corriente al contenedor inmutable como una lista o conjunto. Reduce no recopila sino que aplica todos los elementos a un solo objeto. La identidad. Reducir, toma su identidad, acumula o elementos en la identidad, luego combina múltiples resultados juntos en uno en caso de que se ejecute en paralelo. Reducir es la operación más difícil de comprender. Así que no te sientas mal si no lo consigues todo a la vez. Solo tómate tu tiempo para seguir esta sección y probar los ejercicios al final de la clase. Si te queda alguna duda, no dudes en preguntarlas usando la plataforma. Bien, vamos a sumergirnos. Deep reduce espera un valor inicial llamado la función de identidad que se usa como acumulación y un operador binario utilizado para combinar resultados de subprocesos separados. El perro alfa nos da una buena visión general de lo que hace. Esta identidad nos da el inicio de los resultados. Debe ser pizarra limpia, vacía, tal que agregar cualquier valor del arroyo a esta identidad tenga ese resultado y alterado como producto. Entonces, por cada elemento de la corriente, se acumula en el valor resultante usando la función by. Al igual que con para recopilar, esto no nos muestra lo que hace el operador binario, el combinador. Lo mismo se aplica aquí. El combinador solo se usa para combinar los resultados de múltiples hilos juntos en caso de que el flujo se ejecute en paralelo. Pongámoslo en práctica. Para nuestro ejemplo, elegiremos a todos los clientes en un número entero que represente la cantidad total de dispositivos que pertenecen a esos clientes juntos. Nuestra identidad debe ser un entero. Como resultado, queremos salir de esta corriente. En cuanto al valor. Recuerda cómo agregar cualquier resultado a la identidad debería tener que resultar en alterado como producto. En nuestro caso, tendremos que sumar el tamaño de toda la lista de dispositivos juntos para llegar a nuestros resultados finales. Qué valor de la identidad significa que identidad más el tamaño de la lista de dispositivos es igual a dos. El dispositivo esto, Así es, cero. Entonces nuestra identidad será así. A continuación, necesitamos una función que produzca un elemento de la corriente en esta identidad. Los primeros genéricos utilizados en la función by son un entero que representa el valor actual de los resultados. El subtotal, si se quiere. El segundo uso de genéricos es el elemento del arroyo, que se reducirá al subtotal. El tercer uso de genéricos es el tipo del resultado de la operación un entero. Este tercer genérico debe ser el mismo que el primero, lo cual es lógico ya el primer término genérico representa el subtotal. En caso de una corriente secuencial, ese sería el final de la misma. Pero para permitir el procesamiento paralelo, necesitará operador binario para combinar dos resultados en uno. Usando este operador binario, combinamos los resultados de dos hilos juntos. Esto es repetido por la corriente hasta que todos los resultados de los hilos se fusionan de nuevo en uno. Aquí se llenan en la operación de reducción. Para reiterar, comenzamos con una pizarra limpia y vacía como identidad cero. En nuestro caso. Luego agregamos el tamaño de la lista de dispositivos de cada elemento desde el stream a esta identidad. Si el stream se ejecuta en paralelo, usamos para combinarlos para sumar dos subtotales en uno hasta que nos quede un solo resultado. En nuestro ejemplo, reducimos nuestros objetos complejos en un solo entero. Pero reducido también se puede usar para reducir todos los elementos de una corriente en un solo objeto complejo. Por ejemplo, podríamos reducir a nuestros clientes en un solo cliente que contenga nuestra información. Pero dejaré esa como parte de los ejercicios que puedes hacer por tu cuenta. 13. Resumen y palabra Afterword: Hemos llegado al final de esta clase. Vamos a resumir para ver lo que hemos aprendido en nuestro viaje hacia la API de ocho flujos de Java. Empezamos aprendiendo para qué se utilizan las transmisiones y cómo funcionan. Luego desglosamos cómo se puede crear una expresión lambda a partir de una clase interna anónima gracias a las interfaces funcionales. Discutimos brevemente, pero las interfaces funcionales son, y cuáles usa comúnmente cuando se trabaja con transmisiones. Finalmente, repasamos operaciones intermedias y terminales de uso común. Gracias por ver esta clase. Espero que hayas aprendido lo suficiente sobre las transmisiones para reconocer situaciones en las que puedes y eres capaz de utilizarlas. Si deseas ayudarme a mejorar esta clase y dinos si la encontraste o no útil. Le agradecería que dejara una reseña. Según lo prometido. He preparado algunos ejercicios para que los revises para que veas si puedes aplicar los conocimientos aprendidos durante este curso. Cada ejercicio tiene una solicitud, un resultado esperado para que verifiques si lo hiciste bien. Si hay algo poco claro sobre esta clase ya brindó ejercicios, no dude en enviarme un mensaje con sus preguntas. Te ayudaré lo mejor que pueda. Una vez más. Gracias por ver y hasta la próxima vez.