20250925-InterfacesFuncionales_3 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
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
su
00:04:43
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
a
00:08:27
y ahora
00:08:29
perdón, return
00:08:32
s
00:08:34
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
no
00:15:24
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
X
00:20:14
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
x
00:26:22
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
y
00:26:44
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