Saltar navegación

20250925-InterfacesFuncionales_3 - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 25 de septiembre de 2025 por Raquel G.

4 visualizaciones

Descargar la transcripción

no estás tú para excesos 00:00:00
ya está 00:00:04
vale, bueno pues 00:00:05
estábamos simplemente, que vamos a ver si lo 00:00:08
completamos con lo 00:00:10
básico, que es un poquito con lo que estábamos 00:00:12
¿verdad? habíamos visto 00:00:14
esta cosa mágica 00:00:16
esta cosa 00:00:18
mágica que hace 00:00:24
que cualquier colección de datos 00:00:26
se te serialice 00:00:28
no está bien usada esa palabra 00:00:30
si te ponga en filita 00:00:32
y ya con esta filita 00:00:33
se pueden llamar a unos cuantos 00:00:35
métodos muy útiles 00:00:38
que te van a hacer todo eso 00:00:39
con la fila conjuntamente 00:00:42
entonces ya nos olvidamos de recorrer las colecciones 00:00:43
con nuestros for propios, con nuestros iterator 00:00:46
con todo eso 00:00:48
si podríamos hacerlo 00:00:49
pero bueno, así está más profesional 00:00:51
entonces 00:00:54
¿estás grabando? 00:00:55
sí, está grabando, no ves aquí un punto rojo 00:00:56
entonces, estas funciones 00:00:59
necesitan 00:01:02
que le digamos que hacer 00:01:04
con cada uno 00:01:07
de esos elementos de la fila 00:01:08
y como le decimos ese que hacer 00:01:10
en general con funciones lambda 00:01:12
que las funciones lambda pues no son más que 00:01:14
instancias concretas de una interfaz 00:01:16
funcional, vale 00:01:19
entonces, en particular 00:01:20
los métodos estos 00:01:22
que te ofrece String 00:01:24
pues te dicen que tipo 00:01:26
de función lambda necesitan 00:01:29
entonces hay unas cuantas 00:01:31
y las básicas eran estas 00:01:33
este es un tipo de función 00:01:36
lambda o interfaz 00:01:37
funcional que recibe 00:01:39
uno y se lo come y no hace nada 00:01:41
o sea no devuelve nada 00:01:43
este recibe una cosa 00:01:45
perdón 00:01:47
vale 00:01:49
estas eran las interfaces 00:01:50
funcionales ya estándar en 00:01:53
java 00:01:55
Este recibe un elemento 00:01:56
Y no te devuelve nada 00:01:59
Function, recibe un elemento 00:02:00
Y te devuelve otro, de los tipos que particularicemos 00:02:03
Aquí 00:02:05
Este recibe un elemento y te devuelve 00:02:05
True o false, boolean 00:02:09
Este 00:02:11
No recibe nada y te devuelve algo 00:02:13
Y este recibe 00:02:15
Dos cosas y te devuelve una cosa 00:02:17
Entonces son cinco 00:02:19
Posibles tipos de interfaz 00:02:20
Funcional 00:02:23
y estas funciones, estos métodos de stream, te piden la que toque, una de ellas, ¿vale? 00:02:23
Entonces, por ejemplo, forEach, pues te pide una a la que tú le das un dato y no haga nada. 00:02:33
Ese dato que le das al forEach, ¿cuál es? Todos y cada uno de los elementos de esta fila. 00:02:39
Y con todos y cada uno de los elementos de esta fila, hace lo que le digamos aquí, ¿vale? 00:02:46
El filter, pues también el filter 00:02:52
Le tenemos que pasar un predicado 00:02:55
Que recibe todos y cada uno 00:02:59
De los elementos de la filita 00:03:02
Y te devuelve 00:03:03
El true o false en función de la condición 00:03:06
Que a ti te dé la gana 00:03:08
¿Vale? Dime 00:03:09
Perdón 00:03:10
Está en una grabación 00:03:15
Sí, está subida 00:03:27
¿Vale? 00:03:31
¡Silencio! 00:03:34
Vale 00:03:36
Otra 00:03:36
De los que hay de stream 00:03:43
¿En qué hay unos cuantos? Pues todos estos, que al final se acaban usando tres o cuatro. 00:03:44
Pues el map. El map es el que te transforma la fila con todos sus elementos en otra fila con elementos distintos. 00:03:51
A cada elemento de la fila lo transforma a otro elemento distinto. 00:04:03
Entonces, esta fila la convierte a través del map a otra fila, ¿vale? 00:04:07
no, no, no, map es porque te mapeo 00:04:14
te mapeo cada elemento en otro 00:04:19
y entonces 00:04:21
la función lambda 00:04:23
que hay que pasarle aquí, ¿qué tipo de función 00:04:25
tendrá que ser? una función 00:04:26
porque la función es la que recibe 00:04:28
un elemento y te da otro 00:04:31
pues esta efectivamente 00:04:33
si miramos aquí 00:04:35
map 00:04:37
si miramos su ayuda 00:04:40
pues map 00:04:43
efectivamente 00:04:46
te lo dice 00:04:47
si llamas a map 00:04:49
tienes que pasar una lambda 00:04:50
que sea una función 00:04:53
porque yo con cada uno de los elementos de la filita 00:04:54
voy a obtener otro valor distinto 00:04:57
voy a aplicar esta función 00:04:59
a todos y cada uno de los elementos 00:05:01
entonces por ejemplo 00:05:03
para meter funciones lambda más largas 00:05:04
si nosotros quisiéramos hacer 00:05:06
con esta fila de números 00:05:11
porque estábamos con el ejemplito de la colección 00:05:12
esta que era una lista de enteros 00:05:14
esta de aquí 00:05:16
una lista de enteros 00:05:17
pues vamos a hacer 00:05:20
un código 00:05:21
que yo le paso la lista de enteros 00:05:23
y me devuelve 00:05:27
una colección de string 00:05:28
que sea 00:05:30
una sucesión de 00:05:31
caracteres, de aes por ejemplo 00:05:34
repetida tantas veces 00:05:36
como sea el número 00:05:39
entonces yo puedo querer hacer ese programita 00:05:40
¿no? ese programita 00:05:43
que sea, tengo una lista de números 00:05:44
enteros, uno 00:05:47
en el punto donde está 00:05:48
tengo una lista 00:05:50
de números enteros, uno, dos 00:05:53
cinco, y quiero 00:05:55
obtener una colección que sea 00:05:57
de string 00:05:59
tantas aes como numeritos 00:06:00
esto, esto 00:06:02
esto, vale 00:06:03
pues por ejemplo, ¿vale? quiero hacer como una especie 00:06:06
de histogramas, ¿no? 00:06:08
Una especie de histogramas. Bueno, pues 00:06:10
nosotros, pues aquí haríamos 00:06:12
nuestro for, dentro de 00:06:14
cada for para recorrer la colección, 00:06:16
haríamos a su vez un for anidado 00:06:19
que va concatenando las AEs 00:06:21
tantas veces como me diga 00:06:23
el numerito, luego a la cabeza nos 00:06:25
viene un programa con dos for, 00:06:27
uno dentro de otro. 00:06:29
Pues bueno, esto lo hacemos en una línea, 00:06:31
cascao, ¿vale? 00:06:32
Vale, pues entonces, 00:06:37
pensamos 00:06:38
lo que yo quiero es, tengo una filita 00:06:41
de números y quiero una filita de otra 00:06:43
cosa, pues map 00:06:45
la función map, porque la función 00:06:47
map es la que de una fila de cosas 00:06:49
me lleva a una fila de otra 00:06:51
pues función map, vale, y ahora 00:06:52
¿qué tenemos que meter en la función map? 00:06:54
tenemos que meter 00:06:56
una función lambda que me exprese 00:06:57
la idea de, mi dato 00:07:01
de entrada 00:07:03
que va a ser x 00:07:03
mi dato de entrada que va a ser x 00:07:06
tengo que poner aquí todo el código 00:07:08
necesario para construir 00:07:11
una cadena 00:07:13
con tantas a's por ejemplo 00:07:17
como me diga x 00:07:19
entonces la función lambda ya no es tan rápida 00:07:20
de escribir, porque aquí yo ya 00:07:23
tengo que hacer pues un string 00:07:25
con catenada al string ya es más larga 00:07:27
entonces cuando una función lambda tiene más de una 00:07:29
línea, porque todas las que hemos hecho ahora 00:07:31
tienen solamente una línea 00:07:33
pero si tiene más de una línea 00:07:35
Ya sí que hay que ponerle 00:07:37
El código así, entre llaves 00:07:39
¿Vale? 00:07:41
Hay que ponerlo entre llaves 00:07:44
Efectivamente, vale 00:07:46
Y ahora, aquí ya podemos poner 00:07:51
Cualquier código Java 00:07:56
Entonces nuestro código, pues podría ser 00:07:57
Para 00:08:01
El código normal, pues sería este 00:08:02
¿No? string s 00:08:05
Igual a pipipi 00:08:06
Y ahora 00:08:08
para cada 00:08:09
for 00:08:15
pero mientras si sea menor que x 00:08:18
incrementando y 00:08:23
s más 00:08:24
igual 00:08:27
y ahora 00:08:29
perdón, return 00:08:32
vale 00:08:36
pues esta 00:08:39
¿cuál era la pregunta? 00:08:40
si me piques otro string de enteros 00:08:42
ahí dentro, ¿petaría? 00:08:44
¿otro string de enteros? 00:08:46
enteros.string ahí dentro 00:08:47
¿que si yo llamo a esta variable enteros? 00:08:49
yo creo que no 00:08:52
bueno, no estoy convirtiendo 00:08:53
un string entero, estoy convirtiendo un string 00:08:59
solo un entero, x 00:09:00
sí, string 00:09:02
s, ¿vale? 00:09:04
o sea, ¿qué quieres que cambie para ver si peta? 00:09:07
que si metes otra vez 00:09:09
enteros.stream 00:09:10
enteros.stream 00:09:14
o enteros.toStream 00:09:18
ah, stream 00:09:20
no lo sé, pero para qué quieres hacer esto 00:09:21
esto es 00:09:26
si yo 00:09:28
si yo me grapo el dedo, ¿qué me pasa? 00:09:28
pues no sé, ¿para qué quieres grapar del dedo? 00:09:32
claro, es una sentencia de Java 00:09:34
entonces pues sí, te deja ponerla 00:09:36
entonces, esto ya 00:09:37
De hecho es una función lambda muy larga 00:09:41
Y muy pesada 00:09:43
Entonces, esto ya es código 00:09:44
Cuando la función 00:09:47
Tiene 00:09:50
Más líneas de código 00:09:51
Aquí ya sí que es el reto 00:09:53
Porque fijaos en el caso de arriba 00:09:54
Habíamos hecho ya una función 00:09:57
Habíamos hecho aquí una función 00:09:58
Como ejemplito 00:10:01
Había una función por aquí 00:10:02
Ah, no, es que la cambié ya 00:10:06
Bueno, imaginaos que está 00:10:07
Claro, la cambié 00:10:09
Imaginaos que quisiéramos devolver el doble 00:10:10
pues, claro, era la que estaba 00:10:16
puesta, ¿verdad? 00:10:19
entonces, así 00:10:21
vale, y algo me 00:10:23
falta 00:10:25
desfaz transformadora 00:10:25
no, me falta 00:10:29
quitar esto, ¿no? 00:10:30
vale, ah, es que le había puesto que le devolvía 00:10:33
un string, ¿vale? 00:10:37
vale, en este caso, este ejemplo 00:10:43
de función lambda 00:10:45
transformadora 00:10:47
o función 00:10:49
solo tiene una línea 00:10:50
y esa línea ya es el valor de retorno 00:10:52
en ese caso no se pone el retorno 00:10:54
¿vale? 00:10:56
que es la mayoría de los casos para los que se pueden usar 00:10:57
estas cosas, muchas veces para simplificar 00:11:00
entonces yo tengo un valor, quiero obtener otro en función de él 00:11:02
que lo puedo expresar en una única expresión 00:11:04
pues pongo ahí la expresión y ni retorno ni nada 00:11:05
pero como, pero si para construir 00:11:08
el valor de retorno 00:11:10
tenemos que hacer más líneas 00:11:11
entonces ya sí hay que poner el retorno para indicar 00:11:13
ya cuál es el valor de retorno final 00:11:16
¿Vale? Que es lo que hemos hecho 00:11:18
Aquí, aquí abajo 00:11:20
Entonces 00:11:22
Esto 00:11:25
Ahora retocamos esto un poquito 00:11:28
Esto me devuelve otro stream 00:11:30
O sea, he cambiado 00:11:32
Esta fila en una fila 00:11:33
De elementos distintos 00:11:36
Ahora ya he decidido qué quiero hacer con esta fila 00:11:37
Hay un montón de métodos, por ejemplo 00:11:40
Hay uno que es pasarla a lista 00:11:42
To list 00:11:44
¿Vale? Tengo el to list 00:11:45
Y la paso a lista de string, por ejemplo 00:11:48
O puedo, si lo que quiero es mostrarlo por consola 00:11:51
Pues mostrarlo con un for each 00:11:53
Yo ya decido 00:11:55
Que hago con este string 00:11:57
Porque esto vuelve a ser un string 00:11:58
¿Vale? 00:12:00
Claro, son los mismos elementos 00:12:05
Pero transformados 00:12:07
O sea, es la misma fila 00:12:08
Pero transformada 00:12:10
Entonces, por ejemplo, si lo quiero mostrar por consola 00:12:11
Pues 00:12:14
Pues lo podría mostrar así 00:12:21
¿Vale? Entonces si ejecutamos esto 00:12:26
Efectivamente 00:12:32
Me saldrán las aes 00:12:33
¿Vale? 00:12:36
Vale, entonces 00:12:41
Todo esto venía a cuento 00:12:50
De la clase files 00:12:53
Del paquete jabanío 00:12:56
¿Verdad? 00:12:57
Entonces 00:13:00
Si nos volvemos a ese ejemplo 00:13:01
en el que estábamos, que era 00:13:03
estábamos viendo el contenido de un 00:13:05
fichero, ver fichero 00:13:08
con el fread, pues 00:13:09
íbamos leyendo, concatenábamos 00:13:11
al stream builder y se acabó 00:13:13
ver fichero, vamos a hacerlo de otra manera 00:13:15
pues con la 00:13:18
clase paths, que es la equivalente 00:13:19
a file en javanio 00:13:22
podíamos leer las líneas 00:13:23
directamente con read online 00:13:27
y pasarlas a un stream 00:13:29
Y ahora hacer esto mismo, demostrar el fichero 00:13:31
Ahora lo haremos 00:13:34
Directamente con la fila 00:13:35
¿Vale? 00:13:37
Pero ni siquiera hace falta que saquemos el stream 00:13:39
Porque 00:13:42
La clase files 00:13:42
Ya tiene directamente un método 00:13:45
Que te lo devuelve en stream 00:13:48
Que es lines 00:13:49
Yo creo, si 00:13:52
El método lines es que ya te lo devuelve 00:13:53
Directamente en stream 00:13:56
Joder 00:13:57
es decir, en la clase files 00:14:26
que es en la que estábamos 00:14:33
este me devuelve 00:14:34
todas las líneas en una 00:14:36
lista de cadenas 00:14:37
y este me devuelve ya directamente 00:14:40
un string, una filita con todas las líneas 00:14:43
por si yo quiero operar directamente 00:14:45
ya con el string para hacer cosas 00:14:47
y no hace falta que lo extraiga como lo extraiga aquí 00:14:48
entonces, por ejemplo 00:14:51
para ver otro método 00:14:53
de string 00:14:54
que 00:14:56
nos puede 00:14:57
interesar usar 00:15:00
vale, este método 00:15:01
en particular que estábamos haciendo, ¿para qué era? 00:15:04
para devolver 00:15:06
un string 00:15:08
con el contenido del fichero 00:15:10
para devolver un string con el que tiene el fichero 00:15:12
o lo que es lo mismo 00:15:14
concatenamos todas las líneas y las devolvemos 00:15:15
¿verdad? para eso era ese 00:15:18
fichero, entonces 00:15:20
con el forEach, pues bueno 00:15:21
Lo mostraríamos por consola 00:15:25
Que no es lo que queremos 00:15:27
Con el for each haríamos esto 00:15:28
Filalíneas 00:15:31
Para cada línea 00:15:33
Para cada línea 00:15:39
Pues esto de aquí 00:15:48
Y me sobra esto 00:15:50
A ver 00:16:01
Que me dice este 00:16:09
Perdón, perdón, que es que lo he puesto con el doble punto 00:16:10
Y con el doble punto lógicamente 00:16:15
No hace falta el parámetro de entrada 00:16:17
Vale 00:16:18
Vale, pues este me mostraría el fichero por consola 00:16:19
Pero no es lo que queremos 00:16:25
Lo que queremos es devolver un string con ello 00:16:26
Si ejecutamos esto 00:16:28
Mi fichero 00:16:34
Voy a ver en mi main 00:16:35
Vamos a probar esto en mi main 00:16:38
En mi main le estoy pasando 00:16:40
Nombres txt 00:16:44
Y nombres txt 00:16:45
Era este 00:16:47
Estos nombres 00:16:49
Vale 00:16:51
Pues ahora en mi main llamo a este método 00:16:53
pasándole ese fichero de nombres 00:16:56
y este método 00:16:58
efectivamente 00:17:00
va a ir línea por línea 00:17:01
de esta filita de líneas mostrándolas 00:17:04
vamos a ver, no vaya a ser que hayamos hecho algo mal 00:17:06
que si hemos hecho algo mal 00:17:08
vale, aquí están 00:17:13
pero no es lo que queremos que haga este método 00:17:15
lo que queremos que haga este método 00:17:18
es construir un string 00:17:20
y devolverlo con valor de retorno 00:17:21
entonces el for each 00:17:24
ya no nos vale, porque aquí podríamos 00:17:25
hacer un código dentro del for each 00:17:28
que para cada x 00:17:29
haga una cosita 00:17:31
pero es que no lo va a devolver 00:17:33
porque el for each no devuelve nada 00:17:35
y la función tampoco nos vale 00:17:37
porque la función te devuelve una cosa 00:17:39
para cada elemento de la fila 00:17:41
y la que nosotros devolvemos 00:17:43
necesita todos los elementos de la fila 00:17:45
¿entendéis la situación, no? 00:17:48
entonces aquí hacer un map 00:17:50
no, porque el map 00:17:51
si yo aquí pongo un map 00:17:53
claro, el map transforma cada elemento 00:17:55
en otra cosa 00:17:58
si yo pongo aquí un map con lo que sea 00:17:59
el map 00:18:03
trata cada elemento por separado 00:18:05
en este caso 00:18:07
cada línea del fichero 00:18:09
entonces con cada línea del fichero 00:18:10
haría algo que sería completamente independiente 00:18:12
del resto de líneas y ese algo me lo devolvería 00:18:15
y me lo pondría en otra fila 00:18:17
pero con eso no gano nada 00:18:19
porque el valor final que yo quiero 00:18:20
es un valor agregado, agregado de todas 00:18:23
entonces 00:18:25
¿hay algún método aquí 00:18:27
que me permita obtener un valor 00:18:30
agregado que tenga en cuenta todos los elementos? 00:18:31
pues sí 00:18:35
lo que pasa es que es un poquito 00:18:35
más raro de darle parámetros 00:18:38
pero bueno, no pasa nada 00:18:39
lo vemos, entonces uno 00:18:41
mira, indaga, cotillea 00:18:43
ahora la vida es más fácil 00:18:45
le pregunto a HGPT y te lo dice 00:18:47
¿vale? 00:18:49
pero uno tiene que saber 00:18:52
para que eso le sea una ayuda realmente 00:18:53
Y encuentra el colet 00:18:55
¿Vale? 00:18:59
Encuentra el colet que por el nombre 00:19:01
Por el nombre 00:19:03
Podíamos ya deducir que colet 00:19:06
Hace una agregación 00:19:09
De todos los elementos de la fila 00:19:11
Hace una agrega 00:19:13
Del stream este 00:19:14
Hace un agregado de todos 00:19:16
¿Vale? Pero para hacer ese agregado 00:19:19
Tenemos que darle 00:19:21
Tenemos que darle pautas 00:19:23
en función de lo que queramos hacer 00:19:25
para darle el agregado hay que darle pauta 00:19:28
mediante estos tres parámetros 00:19:30
bueno pues colet 00:19:32
asume 00:19:35
que recibe un 00:19:37
que obtiene un único resultado final 00:19:38
un único resultado 00:19:40
ese resultado final 00:19:41
lo va a meter colet en una cosa que 00:19:43
podemos llamar como una especie de acumulador 00:19:46
una variable acumuladora 00:19:49
nos suena 00:19:51
al séptimo día de la clase de programación 00:19:51
del año pasado 00:19:54
¿Os recordáis? ¿Verdad? El séptimo día en concreto 00:19:55
¿Os recordáis? 00:19:58
Claro 00:20:01
Pues cuando, bueno, no era el séptimo, pero por ahí 00:20:01
Pues cuando hacíamos sumas 00:20:04
acumulativas 00:20:06
Cuando hacíamos la maravillosa 00:20:07
sentencia de 00:20:10
S más igual 00:20:12
Pues sobre S íbamos acumulando 00:20:14
los X que nos iban viniendo 00:20:17
de un for 00:20:20
Entonces, esta es una sentencia que me permite 00:20:20
hacer una suma acumulativa 00:20:24
y ese inicialmente inicializábamos a cero 00:20:25
si es que es una suma 00:20:28
y ese era el acumulador 00:20:29
una variable que funciona conceptualmente 00:20:32
como un acumulador 00:20:34
que va recibiendo esto 00:20:35
pues este colet en realidad 00:20:37
hace una operación acumulativa 00:20:39
¿vale? 00:20:42
entonces, ¿qué es lo que le damos aquí? 00:20:44
aquí le damos 00:20:47
el acumulador 00:20:48
es decir, la variable 00:20:49
sobre la que va a acumular 00:20:52
Claro, la que te va a volver al final 00:20:54
La variable sobre la que va a acumular 00:20:57
El resultado 00:21:00
Final 00:21:02
Y aquí ya sí que le damos 00:21:02
Una función lambda 00:21:05
En este caso sería una bifunction 00:21:06
Y a esta función lambda hay que darle 00:21:09
El acumulador 00:21:11
Que lo hemos generado aquí 00:21:13
El valor de la fila 00:21:15
Y ahora ya 00:21:18
Aquí le ponemos la expresión 00:21:20
De cómo acumulo yo x 00:21:21
como a mí me da la gana 00:21:23
¿cómo acumulo Y 00:21:24
a X? 00:21:27
¿vale? esta sería 00:21:30
la del segundo valor 00:21:31
el segundo valor es una bifunción 00:21:32
recibe dos parámetros 00:21:35
el primero, colect 00:21:36
asume siempre que es el acumulador que has creado aquí 00:21:39
siempre es el acumulador 00:21:42
lo llamas Y, lo llamas como quieras 00:21:43
va a tomar el valor del acumulador que tú hayas creado aquí 00:21:45
¿y quién es? 00:21:47
y es el elemento de la fila 00:21:49
que toca 00:21:51
que esto se va haciendo uno por uno 00:21:53
cada elemento de la fila 00:21:55
y aquí que se devuelve 00:21:56
se devuelve el resultado 00:21:59
de hacer esa acumulación 00:22:02
sobre el acumulador 00:22:03
y eso va cambiando 00:22:05
según va avanzando 00:22:07
la fila, pues el acumulador 00:22:10
irá reflejando 00:22:12
todas y cada una de las llamadas 00:22:13
que se ha hecho a eso, irá reflejando 00:22:15
¿y este tercer parámetro cuál es? 00:22:17
este es un poco 00:22:20
raro 00:22:21
Esto es porque los stream 00:22:22
Pueden trabajar con 00:22:25
Métodos que funcionan en paralelo 00:22:27
Que funcionan con computación 00:22:29
Paralela para que si la fila es muy 00:22:31
Larga, pues 00:22:33
Puedan trabajar en paralelo 00:22:34
Por cachos, si es que eso no afecta 00:22:37
Al resultado final, un map 00:22:39
En realidad podría trabajar por cachos 00:22:41
¿Vale? Entonces 00:22:43
Si se usara 00:22:44
Porque stream puede 00:22:47
Esa forma paralela de trabajar 00:22:49
pues te dice que haces aquí 00:22:51
con esos hilos paralelos que es la alfa 00:22:53
¿en qué se traduce para nosotros? 00:22:55
en poner lo mismo 00:22:58
en poner lo mismo, ya está 00:22:59
haz paralelo o no hagas paralelo 00:23:01
me da igual como lo hagas, pero vas a hacer lo mismo 00:23:03
en ambos casos 00:23:05
no aplicado a esto 00:23:06
yo creo 00:23:09
pero sí en otros contextos 00:23:10
claro 00:23:13
pues entonces, en nuestro caso, ¿qué es lo que queremos? 00:23:13
queremos que todas 00:23:18
las líneas 00:23:19
se fundan en una 00:23:20
se fundan en una 00:23:22
¿qué acumulador necesitamos? 00:23:24
un stream 00:23:28
porque es el que se va a acumular 00:23:28
pero 00:23:30
vamos a acostumbrarnos 00:23:32
ya también 00:23:34
cuando vamos a trabajar con un stream 00:23:35
sobre el que vamos a ir haciendo cosas 00:23:38
acumulando cosas en él 00:23:40
concatenándolo cosas 00:23:42
en lugar de un stream 00:23:43
usar un stream builder 00:23:44
el stream builder 00:23:47
tiene un stream dentro 00:23:50
pero a la hora de usarlo 00:23:52
pues por el tema de los buffers 00:23:53
y por todo eso, se optimiza un poquito 00:23:55
el rendimiento 00:23:57
entonces para no tenerle miedo a ese 00:23:58
stream builder, pues vamos a 00:24:01
me da lo mismo decir que mi variable final 00:24:03
es una string, que es 00:24:05
una stream builder, una stream builder es 00:24:07
un envoltorio de la stream 00:24:09
y de la stream builder saco el stream poniendo 00:24:10
tu stream cuando lo necesite 00:24:13
pero las funciones que me da stream builder 00:24:15
los métodos que me da stream builder 00:24:17
a diferencia de los de stream 00:24:19
que me da los que ya conocemos 00:24:20
o los que me da StreamBuilder 00:24:22
optimizan el funcionamiento del manejo de cadenas 00:24:24
bueno, pues entonces 00:24:26
¿qué queremos? 00:24:28
primer parámetro 00:24:30
función lambda que de la nada 00:24:30
me da algo 00:24:34
un acumulador 00:24:36
perdón 00:24:37
primer parámetro 00:24:39
ah, vale, ahora 00:24:42
es que pensaba que habías puesto algo 00:24:45
no, que es que no se ve 00:24:50
Primer parámetro 00:24:52
Todos tienen que ser funciones lambda 00:24:54
¿Vale? Colet es un método 00:24:56
Primer parámetro, función lambda 00:24:57
Que 00:25:00
Me hace aparecer, así por la buena 00:25:01
Es un stream builder de la nada 00:25:04
¿Qué tipo de interfaz funcional 00:25:05
Es esa? 00:25:08
Una B 00:25:10
Esa, una supplier 00:25:10
Una supplier 00:25:14
En este caso 00:25:16
Una supplier de stream builder 00:25:19
Porque de la nada 00:25:22
Me hace aparecer un objeto stream builder 00:25:25
Eso es lo primero que tengo que hacer ahí 00:25:28
Una función lambda 00:25:30
Que de la nada 00:25:32
Y esta es la nada 00:25:33
De la nada me hace aparecer 00:25:35
Un stream builder 00:25:38
Cuando no hay parámetros de entrada, sí 00:25:43
¡Hala! 00:25:49
Ya tengo el primer parámetro 00:25:56
La supplier que me dice 00:25:57
este es tu acumulador, te lo entrego 00:25:59
ahora 00:26:01
el segundo parámetro 00:26:02
una bifunction 00:26:04
y las bifunction 00:26:05
es que son así obligatoriamente 00:26:08
reciben dos parámetros 00:26:10
y ahí solo me cae una bifunction 00:26:12
el primer parámetro 00:26:14
¿cuál va a ser? 00:26:17
para el colet 00:26:18
ya está 00:26:19
el colet ya sabe 00:26:22
que con x tú te refieres al 00:26:26
acumulador obligatoriamente. Y con 00:26:28
y te refieres al elemento de la fila en la que 00:26:30
estás. Vale, pues entonces 00:26:32
¿qué queremos hacer 00:26:34
con ese y? Pues lo que queremos 00:26:35
hacer con ese y es 00:26:38
acumularlo a x. 00:26:39
x.append 00:26:42
si hubiéramos 00:26:45
cogido en lugar de un newStreamBuilder 00:26:48
un newStream, pues 00:26:50
justo, pues pondríamos 00:26:52
x igual 00:26:53
a x más y. 00:26:56
X igual a X más Y, pues debe ser que está perdido el manejo. 00:26:58
X igual a X más Y, el manejo interno es peor que este, suponemos. 00:27:03
Porque si no, no se usaría tanto. 00:27:10
Vale, y nos pide un tercer parámetro que es para eventual computación paralela. 00:27:13
¿Qué hago cuando lo hagan? 00:27:21
Pues lo mismo, lo mismito. 00:27:23
la misma función lambda 00:27:28
claro, me da igual que 00:27:31
yo voy acumulando 00:27:34
de uno en uno o los voy acumulando 00:27:35
pero los voy acumulando igual 00:27:38
¿qué sentido tendría? 00:27:39
no lo sé 00:27:47
no lo sé 00:27:48
no sé en qué situación 00:27:50
habría que ver en qué situación 00:27:51
se puede hacer una computación 00:27:53
paralela en la cual 00:27:56
pues aquí tendrás que tener en cuenta 00:27:58
Cosas para gestión 00:28:00
De esa computación 00:28:02
Que si no las tienes en cuenta 00:28:03
No te va a funcionar 00:28:06
Y entonces tendrías que ponerlo aquí en líneas añadidas 00:28:07
No lo sé 00:28:09
Tendríamos que pensar un ejemplo 00:28:10
O pedirse lo hecho a GPT 00:28:14
Entonces si tienes una función lambda enorme 00:28:15
La primera, tienes que copiar y pegar la misma 00:28:17
A ver, lo normal es que 00:28:19
Yo es que aquí las estoy poniendo 00:28:22
Que te la hagas a una variable intermedia 00:28:23
Te hagas aquí una bifunción 00:28:25
Y aquí le pasen los dos parámetros 00:28:27
no siempre 00:28:30
¿en qué casos podría no tener sentido pasar el mismo? 00:28:34
pues no se me ocurre ninguno 00:28:37
es lo que me ha preguntado él 00:28:39
si nosotros 00:28:41
estamos haciendo algo 00:28:45
con una fila 00:28:46
y tenemos claro lo que tenemos que hacer 00:28:50
pues nos da igual que lo hagan para él o no 00:28:51
es que queremos hacer eso 00:28:53
entonces ponemos eso las dos veces 00:28:54
Vale, y esto, esto nos va a devolver un valor, nos va a devolver un stream builder, esto ya nos devuelve el collect, nos va a devolver el acumulador, eso es lo que nos devuelve, de hecho para que esto no se pierda un segundito, vamos a escribir aquí para que no se pierda stream builder. 00:28:56
Builder 00:29:27
Vale, y ahora pues vamos a 00:29:31
Y lo devolveríamos 00:29:36
RetuneStreamBuilder 00:29:39
ToStream 00:29:44
Que se me va a acabar, ¿por qué? 00:29:46
Ah, sí, vale 00:29:47
Tienes razón 00:29:50
A ver, hay regleta por ahí 00:29:51
es por no tener cables aquí 00:30:02
porque me voy para atrás, me voy para allá y al final 00:30:13
siempre me 00:30:15
los cargo 00:30:17
vale 00:30:18
pues aquí devolvemos 00:30:19
el acumulador 00:30:25
en tu stream, podría haber puesto aquí que me devolvía 00:30:26
un stream builder directamente y ya está 00:30:29
pero bueno, como me he puesto y me devuelvo un stream 00:30:31
¿vale? 00:30:33
una pregunta, en el tercer 00:30:35
o sea, donde has copiado 00:30:37
la segunda, lo de la 00:30:40
bifunción, le podías poner 00:30:42
un método o algo así, ¿dónde? 00:30:44
ahí, aquí 00:30:46
aquí hay que poner también una bifunción 00:30:47
¿vale? que es 00:30:50
lo que tú harías si trabaja 00:30:51
en paralelo con esa 00:30:54
¿vale? esa es la idea 00:30:55
¿vale? y más allá de ahí 00:30:57
poco más te puedo decir 00:31:00
vamos, podríamos preguntarle 00:31:01
para que nos diga más detalles 00:31:06
por mera curiosidad 00:31:07
si tú haces otra función en la tercera 00:31:08
en el tercer parámetro 00:31:12
¿cuál devuelve? 00:31:13
¿el segundo o el tercero? 00:31:15
no, no, el segundo 00:31:17
la que se hace es aquí 00:31:18
a ver, vamos a 00:31:22
vamos a preguntarle 00:31:23
que nos dé un ejemplito 00:31:25
yo es que no he usado nunca 00:31:26
ese tercer parámetro 00:31:29
entonces no te puedo decir nada que tenga demasiado sentido 00:31:30
entonces, vamos a ver si 00:31:34
nos dice algo con sentido o no 00:31:40
en la función 00:31:43
colet, bueno, tendría que haber puesto 00:31:50
método, pero da igual, de stream 00:31:54
me pones un ejemplo 00:31:58
En el que el tercer parámetro 00:32:03
Para computación 00:32:09
Del stream 00:32:15
En paralelo 00:32:18
Sea interesante 00:32:21
Que sea diferente 00:32:25
Al segundo 00:32:29
A ver si se entra de lo que le he preguntado 00:32:30
Mira, está en pelota como tú 00:32:32
Vale, a ver qué nos dice. 00:32:41
Vamos a ver si la entendemos. 00:32:43
¿Qué? ¿Pero cómo que te has perdido? 00:32:55
Si me lo has preguntado tú. 00:32:57
¿Qué? 00:32:58
Bueno, 00:33:00
su player R es 00:33:02
el tipo este. 00:33:03
Es el acumulador. 00:33:05
Este es el acumulador 00:33:09
Y este es el tipo de datos 00:33:10
De la fila 00:33:13
Vale, entonces 00:33:14
Su player crea el contenedor, el que yo llamo acumulador 00:33:16
Añade un elemento al contenedor 00:33:18
Y este es el combiner 00:33:21
Que combina dos 00:33:23
Contenedores parciales 00:33:25
Cuando usas un string paralelo 00:33:26
¿Vale? 00:33:29
Entonces 00:33:32
Entonces 00:33:32
Cuando usas un string paralelo 00:33:35
si esto ya lo sabemos 00:33:38
vamos a ver un ejemplo interesante 00:33:40
tú puedes usar esta sentencia 00:33:42
de combinación, usas 00:33:45
en un hilo una y en otro hilo la otra 00:33:46
nosotros estamos usando la misma 00:33:49
en los dos 00:33:50
y entonces este 00:33:51
te combina los dos 00:33:54
si usas un string 00:33:56
en paralelo 00:33:58
el string secuencial, el combiner 00:33:59
no se usa 00:34:02
que no tengo ni idea 00:34:03
Vamos a ver, ¿por qué te crees que le he preguntado? 00:34:08
A ver, venga 00:34:15
A ver si entendéis 00:34:16
Este ejemplito 00:34:19
Vamos a ver 00:34:20
Tenemos una lista de palabras 00:34:21
Vale 00:34:24
Ahora, sacamos un stream paralelo 00:34:25
Sacamos un stream 00:34:28
Paralelo para que ahora ya 00:34:31
El tercer elemento 00:34:32
Entre a jugar, ¿vale? 00:34:33
Porque si no, no juega nada 00:34:36
sacamos el string paralelo 00:34:37
vale, va a acumular en un string builder 00:34:39
también 00:34:41
esto que está haciendo aquí 00:34:42
es lo mismo que hemos hecho 00:34:45
nosotros 00:34:47
claro, esto lo que pasa es que 00:34:48
es la forma, esto de aquí 00:34:51
es exactamente igual 00:34:53
que esto 00:34:55
entonces 00:34:56
ayer dijimos 00:35:03
que cuando se usan 00:35:05
los métodos estándares 00:35:07
de instancia o de clase 00:35:09
sin cambiar el parámetro 00:35:11
sin cambiar nada, se podían usar 00:35:13
los dos puntos, eso aplica para el new 00:35:15
estamos usando el constructor 00:35:17
tal cual, sin cambiar el parámetro 00:35:19
que va adentro, sin nada 00:35:21
pues entonces, podemos poner 00:35:22
screen builder, dos puntos y el método que queremos 00:35:24
usar, new 00:35:27
¿vale? entonces 00:35:28
esto 00:35:30
y esto 00:35:34
es lo mismo 00:35:36
es lo mismo, ¿vale? 00:35:38
ahora, este es el acumulador, está claro 00:35:40
el primer combiner 00:35:42
¿qué te hace? 00:35:44
pues sobre el string builder 00:35:47
si tu longitud es mayor que 0 00:35:49
te pone un vacío 00:35:51
y luego además te pone 00:35:52
esto te lo hace para que la primera vez que acumules 00:35:55
no te ponga el vacío delante, ¿vale? 00:35:57
es decir, este acumulador 00:35:59
nos está sacando todas estas 00:36:01
una detrás de otra 00:36:03
con un espacio delante, en medio 00:36:05
¿vale? si es la primera 00:36:07
no pone espacio 00:36:09
y ahora este, que es el que nos angustia 00:36:10
este 00:36:13
¿qué hace aquí? 00:36:14
este es otro combiner diferente 00:36:16
que a ver si deducimos que puede pintar ahí 00:36:18
y porque es interesante y se hace en una 00:36:21
computación paralela 00:36:23
ah bueno, que es que no lo estoy 00:36:24
vale, este otro 00:36:26
coge 00:36:28
los dos stream builders 00:36:31
resultantes de las dos computaciones 00:36:32
en paralelo que está haciendo 00:36:35
se supone que al haber hecho el parallel string 00:36:36
le damos vía libre para que vaya 00:36:38
usando el primer acumulador 00:36:41
en paralelo con trozos 00:36:42
de la fila, le damos vía libre 00:36:45
para que lo haga, bueno pues estos son 00:36:46
los dos trocitos 00:36:49
resultantes 00:36:50
de las computaciones paralelas 00:36:54
son estos dos, los stream builder 00:36:56
y que hace, cuando tengas ya esos dos 00:36:58
cachos construidos porque vas en paralelo 00:37:00
si son mayores 00:37:02
que cero, es decir que 00:37:04
estás ya en medio del proceso, no estás 00:37:06
al principio en ninguno de ellos, 00:37:08
ponles un espacio entre ellos, 00:37:10
pon un espacio al primero y 00:37:13
concatenar el segundo. 00:37:14
¿Vale? Bueno, pues entonces, 00:37:16
esto tiene bastante sentido, ¿verdad? Lo que está haciendo. 00:37:18
Ahora ya quizás sí que nos queda más claro. 00:37:20
Este programa, este 00:37:23
método que nos ofrece, ¿qué quería hacer? 00:37:24
Tenía un montón de palabras 00:37:26
y las quería poner todas juntas, 00:37:27
separadas por espacio. 00:37:30
La primera pregunta que nos hacemos, 00:37:32
¿esto tiene sentido hacerlo por Caxos? 00:37:34
o no puedo hacerlo por cachos 00:37:36
y luego unir los cachos 00:37:38
porque si no puedo hacerlo por cachos y luego unir 00:37:39
los cachos, me olvido del 00:37:42
para el string, del combiner final 00:37:43
y de todo eso, hago string 00:37:46
en el tercer parámetro 00:37:48
casco lo mismo o cualquier cosa 00:37:49
a mi es que me mosquea lo del 00:37:52
cuando no es para ello, casi no lo uso, así que casi me he mosqueado 00:37:53
por eso yo cascaría lo mismo 00:37:56
¿vale? siempre, porque así nunca 00:37:58
jamás vais a tener un error 00:38:00
¿vale? pero si yo veo que mi problema 00:38:01
lo puedo hacer por cachos, poner a 2 00:38:04
oye tú, júntame 00:38:07
estas palabras con espacios 00:38:08
y tú en paralelo, júntame estas con espacios 00:38:10
y luego ya me encargaré del combiner final 00:38:12
si identifico que ese problema 00:38:15
se puede hacer así, casco el 00:38:16
para el stream, entonces en este 00:38:18
si se puede hacer así, yo puedo 00:38:21
juntar unas palabritas, luego juntar otras 00:38:22
y luego el agregado 00:38:24
bueno, pues entonces ahora ya 00:38:26
hago el acumulador 00:38:28
el segundo parámetro sería 00:38:30
lo que se hace en cada hilo por separado 00:38:32
lo que se hace en cada hilo 00:38:35
que en este caso es 00:38:36
esto 00:38:38
lo mismo que hemos hecho nosotros, lo que se hace en cada hilo 00:38:42
y luego 00:38:45
en el combiner final le digo 00:38:46
con tus dos resultados 00:38:48
parciales, según te vayan 00:38:51
llegando resultados parciales 00:38:53
que los resultados parciales van a ser 00:38:55
siempre dos acumuladores, claro 00:38:57
según te van llegando resultados parciales 00:38:59
haz esto, que en este caso 00:39:01
los resultados parciales a su vez implican 00:39:03
pegarlos entre sí 00:39:05
pero es un poco lo que has hecho antes 00:39:06
lo que pasa que con 00:39:09
claro, lo que pasa es que le estás dando la orden 00:39:10
le estás diciendo, oye 00:39:13
como no vas a trabajar 00:39:14
en un único hilo, coge una palabra 00:39:16
pégala, coge una palabra, pégala, coge una palabra 00:39:19
pégala, sino que vas a 00:39:21
tener a dos tíos, este cogiendo 00:39:23
palabras y pegando, este cogiendo palabras y pegando 00:39:25
con los dos cachos que te den, ¿qué quieres que haga? 00:39:27
pues con los dos cachos 00:39:30
que te den, quiero que hagas esto 00:39:31
Este combiner tercero 00:39:32
efectivamente tiene sentido 00:39:37
si tú has generado el stream 00:39:38
con ParallelStream 00:39:41
porque con ese 00:39:42
habilitas 00:39:45
que trabaje así 00:39:46
encargándoselo a dos tíos distintos 00:39:49
pero solo habilitarás 00:39:50
que trabaje con dos tíos distintos 00:39:52
si el problema 00:39:54
por su propia naturaleza te lo permite 00:39:56
Hay problemas en los que 00:39:58
tienes que ir por partes 00:40:00
¿vale? por ejemplo 00:40:02
que un programa 00:40:04
que tienes una lista de números enteros y te los suma 00:40:06
pues también podrías habilitar el paralelo 00:40:08
un tío me suma estos cachos 00:40:10
otro tío me suma estos números 00:40:12
con los dos acumuladores 00:40:14
que serían dos integer 00:40:17
¿vale? 00:40:18
le digo que me sume los dos 00:40:20
dime 00:40:22
entiendo 00:40:24
si esto es bifunction 00:40:28
es que son dos cachos 00:40:30
y por la cabecera del método 00:40:32
creo que te dice que tiene que ser bifunction 00:40:35
entonces yo no sé si habrá 00:40:37
claro, entonces si es bifunction 00:40:39
ese solo te permite 00:40:41
dos cachos 00:40:43
vale 00:40:44
bueno, pues este método 00:40:45
nuestro nos devolvería 00:40:58
todas las 00:41:00
entonces, una tras otra 00:41:01
una tras otra 00:41:04
sí, esto lo podríamos haber hecho en paralelo 00:41:04
también, porque de hecho es el mismo 00:41:08
que el otro 00:41:10
lo podríamos haber hecho en paralelo 00:41:10
también, vale 00:41:12
si ejecutamos 00:41:14
el ver fichero 2 ahora 00:41:17
aquí 00:41:18
en nuestro main, debería sacarnoslos 00:41:19
también, mi duda es el punto y coma 00:41:23
perdón, el punto y coma, el salto de línea 00:41:24
si deberíamos haber puesto 00:41:26
un salto de línea, si efectivamente 00:41:29
deberíamos haber puesto un salto de línea 00:41:31
entonces deberíamos 00:41:32
a este 00:41:34
acumulador 00:41:36
de aquí, append y punto append, salto de línea. Ahora entiendo que ya sí. Bueno, pues 00:41:39
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Segundo Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
4
Fecha:
25 de septiembre de 2025 - 16:46
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
42′ 08″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
806.32 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid