20250923-InterfacesFuncionales_2 - 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:
bueno pues todo esto
00:00:00
de las interfaces funcionales
00:00:03
y las funciones lambda
00:00:05
nos ha surgido a nosotros
00:00:06
por la utilidad
00:00:09
de usar la clase stream
00:00:11
que podemos asociar a cualquier
00:00:13
colección de datos
00:00:15
nos vino a raíz
00:00:16
de ahí
00:00:19
bueno antes
00:00:20
de meternos con ella porque vamos a tener que sacarlo
00:00:23
como se usan mucho
00:00:25
Java
00:00:27
y muchos de los paquetes que se pueden poner
00:00:30
coger de ahí que no están en la implementación
00:00:32
estándar de Java, pero bueno
00:00:34
muchos de los de la implementación estándar de Java
00:00:36
como por ejemplo
00:00:38
la clase stream
00:00:39
pues muchas clases
00:00:41
de la distribución estándar de Java
00:00:43
tienen métodos
00:00:45
que necesitan para funcionar
00:00:46
instancias de interfaces
00:00:50
funcionales
00:00:52
entonces si tú quieres usar esos métodos
00:00:53
tienes que dar una instancia
00:00:56
de una interfaz funcional
00:00:57
que responda exactamente
00:00:59
a los datos de entrada y salida
00:01:01
que necesita ese método para trabajar
00:01:03
que responda exactamente
00:01:05
entonces, dime
00:01:06
no sabría
00:01:07
a ver, se puede hacer una relación
00:01:15
pero creo que no es lo que tienes en mente
00:01:17
olvídate del comparable por ahora
00:01:18
vale, entonces
00:01:20
para facilitar de nuevo
00:01:22
para homogeneizar esto
00:01:25
Java tiene
00:01:27
en un paquete
00:01:29
4, 5, 6, 7
00:01:31
o sea unas cuantas
00:01:33
unas cuantas interfaces con métodos vacíos
00:01:34
y
00:01:37
a su vez otras clases de Java
00:01:39
para trabajar necesitan
00:01:41
que tú pases instancias
00:01:43
de esas interfaces
00:01:45
y esas interfaces recogen
00:01:46
las situaciones más habituales
00:01:49
no recibir ningún parámetro y devolver
00:01:50
uno, recibir un parámetro
00:01:53
y devolver otro
00:01:55
Recibir dos y devolver uno
00:01:56
Recibir uno y no devolver ninguno
00:01:58
Es decir, hay un montón de situaciones
00:02:00
En cuanto a datos de entrada y salida
00:02:03
Que son esas
00:02:05
Luego ya como se actúe por dentro es distinto
00:02:08
Lo normal es usar blanda
00:02:11
Entonces, repito
00:02:13
Los comportamientos
00:02:17
Aparte de por lo que hacen
00:02:21
Que esa es la implementación
00:02:23
se caracterizan por los datos que entregan
00:02:25
y reciben, es decir, por los parámetros de entrada
00:02:29
y lo que devuelven, por eso se caracterizan los métodos
00:02:32
por los datos que reciben
00:02:35
y lo que devuelven en caso de devolver algo
00:02:38
y luego por su implementación
00:02:40
bueno, pues Java hace una especie de clasificación de métodos
00:02:42
en función de lo que dan y lo que reciben
00:02:46
hace una especie de clasificación de métodos
00:02:48
lo mete en interfaces funcionales
00:02:51
Y luego tú ya cuando quieres hacer métodos que den y reciban esa combinación de parámetros, haces una implementación de esa interfaz funcional.
00:02:54
A ver, me explico.
00:03:03
Vamos a hacer aquí otra clase para hacer ejemplos estándar, yo que sé, la voy a llamar.
00:03:08
Ejemplos estándar de Java.
00:03:21
Vale, pues por ejemplo, Java tiene una interfaz funcional.
00:03:30
A ver, todo eso es un poco de memoria
00:03:35
Así que en algún momento igual hay que recorrer
00:03:37
Una interfaz funcional
00:03:39
Ahora le cambio el tipo genérico
00:03:41
Que se llama así
00:03:43
Bueno, le voy a dar un tipo para que le importe
00:03:45
Vale, pues esta interfaz funcional
00:04:03
Que yo siempre puedo implementar si la necesito
00:04:06
Es genérica
00:04:08
Esto si nos vamos a su declaración
00:04:11
Que es esta
00:04:14
Es una interfaz genérica
00:04:23
Es decir, yo cuando la instancio
00:04:25
Particularizo el tipo de dato que quiero
00:04:29
Esto de las clases genéricas
00:04:31
Lo recordáis, ¿verdad?
00:04:34
Tú puedes declarar una clase
00:04:35
Dependiendo
00:04:37
De un tipo de dato que todavía desconoces
00:04:40
Pero la declaras igual
00:04:42
Y la declaras
00:04:44
Trabajando con este tipo genérico
00:04:47
Cuando luego tú instancias esto
00:04:49
Ya dices qué tipo en concreto quieres
00:04:50
Lo que hemos hecho toda la vida con las colecciones
00:04:53
las colecciones, las listas
00:04:55
los sets son genéricos
00:04:57
pero cuando los instanciamos
00:04:59
ya damos un tipo de dato, ¿vale?
00:05:01
bueno, pues la interfaz consumer
00:05:03
este es su único
00:05:05
método abstracto
00:05:07
recibe un valor
00:05:08
y no devuelve nada, por eso se la llama
00:05:10
consumidora, le metes y no saca
00:05:13
nada
00:05:15
¿vale? entonces es un tipo
00:05:15
de interfaz que usaremos cuando
00:05:18
alguien me pida un comportamiento
00:05:21
en el cual
00:05:23
Doy un dato y no recibo nada
00:05:24
Ese comportamiento luego yo lo implemento
00:05:26
Como me dé la gana
00:05:28
Vale, pues entonces
00:05:29
La
00:05:31
Esta interfaz consumer, si yo la quiero implementar
00:05:33
Pues por ejemplo
00:05:36
Una posibilidad, siempre va a tener
00:05:37
El x aquí, porque recibe
00:05:40
Un valor, un único valor
00:05:42
Luego siempre va a tener el x aquí
00:05:44
¿Y qué es lo que va a hacer?
00:05:46
Lo que sea que haga
00:05:48
Pero no puede devolver nada
00:05:49
Pues
00:05:51
a lo mejor yo que sé
00:05:53
conectarse con algo, mandarlo
00:05:56
aquí lo más fácil que podemos hacer es mostrar
00:05:59
por consola, entonces esta sería
00:06:01
y vamos a aprovechar de hecho para
00:06:03
meter otra cosa
00:06:05
esta sería
00:06:06
una
00:06:09
implementación válida
00:06:11
de un consumidor
00:06:14
¿vale? recibe un valor
00:06:15
y no me retorna nada
00:06:18
entonces
00:06:20
esto es una implementación válida
00:06:22
de este método de aquí
00:06:24
si yo la quisiera implementar
00:06:26
a este consumidor de otra manera
00:06:31
por ejemplo
00:06:33
dándole dos parámetros
00:06:34
pues me diría
00:06:36
no, no, no, esto no es una implementación
00:06:38
válida de esta interfaz
00:06:41
solo necesito
00:06:43
me tienes que pasar uno
00:06:45
y solo uno
00:06:47
esta si sería válida
00:06:48
vale, vamos a poner
00:06:53
los cuatro básicos y luego volvemos aquí
00:06:55
otra vez un poquito porque esto, hay otra
00:06:56
forma de escribirlo que es la que vais a ver
00:06:59
siempre. Bueno, ¿qué otras interfaces
00:07:01
estándar tenemos?
00:07:03
Tenemos la que recibe
00:07:05
un valor y te devuelve un valor.
00:07:07
Esa, si no me falla
00:07:09
mi memoria,
00:07:11
se llama
00:07:16
function. ¿Vale?
00:07:17
La vamos a particularizar entero.
00:07:20
Por ejemplo, esta
00:07:21
es la que transforma un valor en otro.
00:07:30
La función matemática
00:07:33
de toda la vida, le das un valor y te saca otra función matemática
00:07:34
de toda la vida, vale, pues
00:07:36
una implementación
00:07:38
pues mira, esta sería
00:07:39
una implementación
00:07:44
válida
00:07:46
la importamos, están en Java útil
00:07:48
como veis, las interfaces
00:07:52
funcionales
00:07:54
y
00:07:56
que he escrito mal
00:07:57
yo en esta interfaz
00:08:03
a ver
00:08:04
ah, claro, no, perdón, perdón
00:08:06
¿Qué tontería? Vale, función es genérica, pero necesita dos tipos de datos, el de entrada y el que devuelve. Vale, lógicamente, función necesita el de entrada y el que devuelve. Vale, de hecho, si la abrimos, aquí está función, que es genérica, depende del que, el dato que recibe y el que devuelve.
00:08:10
y este es su único método abstracto
00:08:39
recibes del tipo T
00:08:42
y devuelves del tipo R
00:08:43
¿vale?
00:08:45
bueno, pues esta implementación estaría bien
00:08:51
le paso un entero y devuelvo un entero
00:08:53
¿qué otra?
00:08:55
la de predicado
00:08:58
esta
00:09:00
recibe un valor
00:09:02
y devuelve un boolean
00:09:04
se supone que verifica
00:09:05
si se cumple la condición con ese valor
00:09:07
Por ejemplo, vamos a hacer
00:09:09
Pues que compruebes
00:09:12
Si el número es par, yo que sé
00:09:17
Interfaz
00:09:18
Condicional
00:09:21
O comprobadora, venga, vale, me gusta más
00:09:22
Comprobadora
00:09:24
Pues esta podría ser
00:09:27
Mi dato de entrada
00:09:29
Me devuelves
00:09:31
X por ciento
00:09:34
Dos igual a cero
00:09:36
Importamos
00:09:37
Vale
00:09:42
Cuando solo tiene una línea, la función lambda solo tiene una línea que coincide con el valor de retorno, no se pone return, ¿vale?
00:09:46
Pero la función lambda puede tener varias líneas.
00:09:54
Entonces, ahí creo recordar que la última, que es la de valor, hay que poner return, la línea que tú explicas, el valor de retorno, y ahí sí que hay que poner return.
00:09:58
Pero si solo tiene una línea, que es el valor de retorno, no se pone, ¿vale?
00:10:06
Pero bueno, estos detalles de sintaxis
00:10:11
En cualquier lado están bien especificados
00:10:13
Vale, y cuál es la otra
00:10:18
Ah, el supplier
00:10:22
Este en lugar de consumir
00:10:25
Te da
00:10:31
Tú no le das nada
00:10:32
Y te da algo
00:10:34
Así es de generoso
00:10:35
Este
00:10:37
Por ejemplo
00:10:38
Este es así de magnífico
00:10:42
Claro
00:10:44
Interfaz
00:10:46
Donadora
00:10:49
No, claro
00:10:51
Entonces, aquí pones
00:10:53
Sí, directa
00:10:56
No, paréntesis vacíos
00:10:58
Paréntesis vacíos
00:10:59
¿Tienes que poner x o algo?
00:11:01
No, porque no recibe nada
00:11:03
Entonces, x por ejemplo
00:11:05
Pues vamos a ver
00:11:07
Math.ran
00:11:09
Bueno, le voy a poner double
00:11:17
Porque esto te lo devolvían Dabble, ¿verdad?
00:11:19
¿Y random?
00:11:27
¿No existe random?
00:11:28
Vale
00:11:30
Pues ya está
00:11:31
Este es un donador de cosas
00:11:34
Donador de cosas
00:11:36
Y este es su método
00:11:39
¿Vale?
00:11:43
Así es tan mono
00:11:47
Como veis
00:11:48
La gran mayoría de las cosas
00:11:49
Que tiene la distribución de Java
00:11:52
No tiene nada
00:11:54
esta interfaz es esta línea
00:11:56
punto pelota
00:11:59
pero claro, gracias a que todo está
00:12:00
distribuido en interfaces, cosas que
00:12:03
implementan, diferentes paquetes
00:12:05
gracias a ese diseño
00:12:07
luego
00:12:09
la reutilización
00:12:10
y sobre todo la escritura de códigos
00:12:12
universales es tan sencilla
00:12:15
entonces
00:12:17
Java
00:12:19
empezó con sus principios básicos
00:12:20
fenomenal, ya se quedaron
00:12:22
y a partir de ahí
00:12:24
todo lo que ha hecho
00:12:26
que gane territorio
00:12:29
ha sido por cuestiones de mejora
00:12:31
en el diseño, por diseñar
00:12:33
de una manera o de otra, no por aportaciones
00:12:35
de lo que ya hace, lo que ya hace ya lo sabemos
00:12:37
igual crear clases y métodos, se acabó
00:12:39
no hace más, todo lo demás
00:12:41
que le permite ganar terreno
00:12:43
es mejoras en el diseño de las clases
00:12:44
pues lo de hacer
00:12:47
interfaces funcionales
00:12:49
es una mejora en el diseño enorme
00:12:50
muchísimo
00:12:52
muchísimoísimo
00:12:56
de todas formas cuando me preguntáis
00:12:59
eso se usa mucho
00:13:03
entended que mi formación es limitada
00:13:04
porque es que yo vivo encerrada aquí
00:13:07
de lo que veo, de lo que me cuentan
00:13:08
de lo que
00:13:11
no, pero
00:13:12
bueno ya, pero es que entonces
00:13:15
cualquier cambio que hagas seguramente
00:13:20
tenga más impacto en más clases
00:13:23
que si lo haces respetando este diseño, casi seguro
00:13:25
habría que ver luego cada caso en concreto
00:13:27
pero el objetivo de una aplicación
00:13:29
es que, como va
00:13:31
si es buena, tendrá un tiempo
00:13:33
de mantenimiento grande, esa fase será grande
00:13:35
entonces el objetivo es que
00:13:37
cada incorporación dentro
00:13:39
de la fase de mantenimiento, no implique
00:13:41
cambiar 200.000 clases, porque si
00:13:43
implica esa aplicación, tendría un diseño horroroso
00:13:45
y al final alguien va a decir
00:13:47
mira, la hago de nueva, tiempo perdido
00:13:49
dinero gastado
00:13:51
Entonces todo esto
00:13:53
Está orientado a que
00:13:55
Cualquier incorporación en una aplicación
00:13:57
Implique retocar lo mínimo
00:13:59
En código
00:14:01
Vale, bueno
00:14:02
Vamos a incorporar la quinta
00:14:05
Porque me da pena dejarla
00:14:06
Bueno, hay más, en bifunción habrá más
00:14:08
De hecho, como somos
00:14:11
Hiper mega curiosos
00:14:13
Vamos a
00:14:14
Abrir aquí
00:14:17
Java útil
00:14:19
Todo esto son
00:14:20
Interfaces funcionales
00:14:34
¿Ves?
00:14:36
De las
00:14:40
¿Vale? Pero las básicas
00:14:41
Son estas cinco
00:14:43
Que voy a poner aquí
00:14:44
Tampoco había tantas
00:14:47
Igual había unas treinta o por ahí
00:14:50
¿Vale?
00:14:51
Y la quinta
00:14:53
Sí
00:14:54
Las más habituales
00:14:57
Bifunction
00:15:01
Bifunction
00:15:02
Le pasas dos cosas
00:15:04
Y te devuelve una
00:15:07
¿Vale?
00:15:08
Esta es la function
00:15:10
Por ejemplo
00:15:11
Le paso
00:15:16
Esto
00:15:17
Y me devuelve el número elevado al otro
00:15:20
Ya ves tú
00:15:23
Le tenemos que pasar
00:15:23
Interfaz
00:15:26
Doble donadora
00:15:30
No, doble donadora no
00:15:32
Eso
00:15:34
Interfaz
00:15:36
Doble transformadora, yo que sé
00:15:38
Transformadora
00:15:40
Esta interfaz, doble transformadora
00:15:44
Exacto
00:15:48
Le pasas x y te devuelve lo que a ti te dé la gana
00:15:50
Que en este caso vamos a
00:15:53
Hacer pues
00:15:54
Mag.pwn
00:15:55
x y
00:15:58
Punto y coma
00:16:00
Y que he hecho mal
00:16:05
ah, vale, que Pau te devuelve
00:16:07
integer, entonces vamos a cambiar aquí el genérico
00:16:16
para que sea
00:16:19
dabble, vale
00:16:20
que Pau te devuelve a dabble
00:16:24
pues cambiamos aquí a dabble
00:16:26
entonces
00:16:27
para
00:16:39
ahora, claro
00:16:47
Claro, la que hemos ido abriendo cada vez
00:16:50
Supplier tiene
00:16:53
Esta, ya está, no tiene más
00:16:54
Esto se ha acabado, una solo
00:16:56
Son interfaces funcionales
00:16:57
Y solo tienen una
00:17:02
Vale, pues entonces
00:17:03
¿Para qué nos pueden servir
00:17:09
Instancias?
00:17:11
Tú, si sirve bien
00:17:14
Y si no, nada
00:17:16
Así en la vida lo podemos ir
00:17:17
Hay cosas que solamente se disfrutan.
00:17:18
¿Qué es lo de las funciones lambda?
00:17:20
Es solo una manera de instanciar un intervalo.
00:17:25
Exactamente, es solo una manera de instanciarla sin necesidad de hacerte una clase que tenga el código dentro y hacer un new de esa clase.
00:17:28
Te ahorras escribir la clase y hacer el new.
00:17:35
Porque con la función lambda harás el código del método y punto pelota.
00:17:37
Vale.
00:17:41
bueno, pues para qué nos sirve
00:17:42
el tener yo instancias
00:17:45
de estas interfaces
00:17:47
que he dicho que son estándar
00:17:49
que ya las trae la máquina
00:17:51
que ya las trae la distribución de Java
00:17:52
bueno, pues porque Java a su vez
00:17:54
me ofrece un montón de métodos
00:17:56
y de cosas que necesitan
00:17:59
consumidores, funciones
00:18:01
predicados, etcétera
00:18:03
entonces, si yo veo
00:18:05
que me interesa, que me viene fenomenal
00:18:06
usar un método de Java
00:18:08
que necesita un consumidor
00:18:10
pues me instancio el consumidor
00:18:12
por ejemplo
00:18:15
con los streams de las colecciones
00:18:16
que es por lo que ha surgido todo este rollo
00:18:19
entonces
00:18:21
por ejemplo
00:18:22
bueno para
00:18:26
para hacer algo con él
00:18:31
que no implica entregarlo
00:18:33
como valor de retorno, como hombre lo puedes
00:18:35
mostrar, pues yo que sé
00:18:37
Por ejemplo
00:18:38
Vamos a hacernos una lista de enteros
00:18:45
Porque como tenemos aquí
00:18:48
Y ahora
00:19:00
Venga, por ejemplo
00:19:01
Vamos a hacernos una lista de números enteros
00:19:15
¿Qué habéis hecho?
00:19:19
Eso es lo que pasa cuando
00:19:28
Cuando mandamos a Brian
00:19:29
Brian ha ido a los de educación física
00:19:30
Ahí tiene un montón de trabajo
00:19:35
El departamento de educación física
00:19:36
Tiene mucho trabajo
00:19:37
Vale
00:19:40
Venga, pues entonces
00:19:43
Por ejemplo, uno podría
00:19:45
Querer
00:19:47
A ver, mis ejemplos
00:19:49
Ejemplos, mi capacidad de improvisación de ejemplos muchas veces no es la más adecuada, pero vosotros os adaptáis porque sois así de majos.
00:19:52
Bueno, pues, por ejemplo, ahora podríamos querer, por favor, muéstrame todos los números enteros.
00:20:02
Vamos a aprovechar una que tengamos hecha, que era multiplicar por dos.
00:20:10
Muéstrame el doble de todos y cada uno de los números que hay en la lista.
00:20:15
Bueno, primero vamos a llenarla con números
00:20:20
Porque si no, esto es un
00:20:21
Que vamos a ponerle
00:20:23
Diez numeritos
00:20:32
Pues vamos a hacer
00:20:34
Enteros.add
00:20:40
Más punto random
00:20:43
Por cien
00:20:48
Y hacemos el casting a int
00:20:53
Ahí tenemos una lista rápida
00:20:55
De números enteros, aleatorios
00:21:06
Pseudo aleatorios
00:21:07
La aleatoriedad no existe en el universo
00:21:10
Sedo aleatorios entre
00:21:11
0 y 100
00:21:14
Más o menos
00:21:16
Vale, ahora
00:21:17
Mostramos el doble
00:21:19
De todos ellos
00:21:26
Sin esto de los streams
00:21:28
Ni lambdas
00:21:32
Ni nada de eso
00:21:33
Pues
00:21:35
Haríamos esto, ¿verdad?
00:21:38
Sí, soy por 2.
00:21:56
Vale.
00:21:59
En este caso,
00:22:01
no ha quedado muy largo
00:22:02
porque lo que yo tengo que mostrar
00:22:04
es el doble del numerito
00:22:07
y el doble del numerito que multiplicar por 2 ya está.
00:22:08
Pero podría ser que lo que yo tengo que mostrar
00:22:11
es algo que implica
00:22:13
una operativa con el numerito
00:22:15
que la tengo que poner delante
00:22:17
y ya se queda más largo y queda más feo y todo eso.
00:22:19
Pero bueno, en cualquier caso,
00:22:21
tengo que poner dos líneas.
00:22:22
esto con la filosofía actual
00:22:23
de mínimo esfuerzo
00:22:27
pues porque voy a poner dos líneas
00:22:29
y puedo poner una
00:22:30
que va a quedar mucho más claro
00:22:31
vale, pues entonces
00:22:33
¿qué estamos haciendo aquí?
00:22:35
aplicar a todos y cada uno
00:22:39
de los elementos de la lista
00:22:40
¿el qué?
00:22:41
una función de tipo
00:22:44
de la que hemos visto arriba, ¿cuál?
00:22:46
no, porque estamos mostrando
00:22:50
no estamos devolviendo un valor
00:22:51
La que no te gustaba
00:22:53
Una consumidora
00:22:56
Vale, pues entonces
00:22:57
Nosotros ahora podemos hacer
00:22:59
Esto
00:23:01
Cogemos nuestra lista de enteros
00:23:04
La ponemos en filita con el stream
00:23:09
Y ahora
00:23:14
Al ponerla en filita con el stream
00:23:16
Se me abren un montón de cosas
00:23:19
Que el stream puede hacer
00:23:22
¿Vale?
00:23:23
por ejemplo
00:23:24
entre ellas, al final uno acaba haciendo
00:23:27
cuatro cosas
00:23:29
de estas, el for each, el filter, el map
00:23:31
cuatro cosas y ya está
00:23:33
y se me abre
00:23:35
un montón de posibilidades
00:23:37
entonces yo busco aquí
00:23:39
y encuentro
00:23:41
el for each
00:23:44
que
00:23:47
efectivamente
00:23:49
necesita un consumer
00:23:50
necesita
00:23:52
una interfaz funcional
00:23:54
de tipo consumer
00:23:58
que reciba algo
00:23:59
que implemente un entero.
00:24:00
¿Vale?
00:24:02
Es lo que necesita
00:24:03
porque mi lista es de enteros.
00:24:05
¿Vale?
00:24:06
Como mi lista es de enteros,
00:24:07
pues él necesita
00:24:09
un consumidor.
00:24:10
¿Vale?
00:24:12
Pues entonces
00:24:12
o le doy ya la lambda
00:24:13
directamente
00:24:15
al for each,
00:24:15
cojo el for each
00:24:19
y entonces el for each
00:24:20
necesita un consumer.
00:24:21
Pues le podría dar la lambda
00:24:23
o como ya la tengo
00:24:24
escrita aquí,
00:24:25
Le puedo dar esto
00:24:26
Interfaz consumidora
00:24:28
¿Vale?
00:24:30
Ah, es que mi consumer era con stream
00:24:42
No pasa nada, lo cambio a Integer
00:24:45
Integer
00:24:47
Vale, ya está
00:24:49
Porque aquí no hay que especificar el tipo de entrada
00:24:51
Se supone que ya se...
00:24:54
Vale, lo cambio a Integer
00:24:56
Ahora ya sí
00:24:57
Entonces
00:24:58
He encontrado el método
00:25:00
Que ya se nos queda en la cabeza
00:25:02
Que lo que hace es
00:25:05
ir uno por uno, fila por filita
00:25:06
aplicando
00:25:09
el método de esta interfaz
00:25:11
funcional, y ese método tiene que
00:25:13
ser un consumidor, es decir
00:25:15
recibe todos y cada uno de los elementos de la fila
00:25:17
y hace lo que sea
00:25:19
sin devolver retorno
00:25:21
efectivamente
00:25:23
sería normal, entonces
00:25:25
si nosotros ejecutamos esto
00:25:27
pues
00:25:29
sí, porque tiene que haber 20
00:25:30
Espérate, nos está cuadrando
00:25:43
Esos son los numeritos
00:25:49
Primero los muestra, multiplicados por 2
00:25:50
Y luego tendría que
00:25:53
Es coherente lo que sale
00:25:55
No acabo de entender
00:25:59
Sí, ahora
00:26:06
Espera, vamos a quitar esto
00:26:10
Para enterarnos
00:26:12
vale, te lo muestra multiplicado por 2
00:26:13
y ahora
00:26:20
ah, bueno, claro, me lo muestra así
00:26:22
porque mi consumidor no me lo
00:26:29
multiplica, o sea, claro
00:26:31
para que me muestre lo mismo, vale, vale, porque mi consumidor
00:26:33
no te lo multiplica por 2
00:26:35
vale, vale, entonces ahora ya sí
00:26:36
me tendría que mostrar dos veces lo mismo
00:26:39
efectivamente
00:26:41
me hace
00:26:44
esta la
00:26:46
y esto lo otro.
00:26:48
Para que me lo
00:26:54
muestre, lo multiplica por dos.
00:26:55
¿Vale?
00:26:58
Vale, entonces
00:26:59
pues una línea.
00:27:00
Lo normal es...
00:27:04
Una línea y lo de arriba.
00:27:05
Claro, claro.
00:27:06
Ya, lo de arriba
00:27:08
dos. Vale.
00:27:10
pero porque en este caso
00:27:12
pues la lambda era muy sencillita
00:27:14
era esto, vale, una línea
00:27:16
pero
00:27:18
¿y lo bonito que es esto?
00:27:19
que bonito
00:27:21
normalmente no se ve bonito
00:27:22
claro, así no se ve bonito
00:27:24
porque esto lo hace confuso
00:27:27
si uno ve este código
00:27:30
tiene que decir, ¿y esto que hace?
00:27:31
y te tienes que ir buscando
00:27:34
entonces lo normal es meter ahí la lambda
00:27:34
vale, entonces lo normal
00:27:38
es haber hecho esto
00:27:40
for each
00:27:42
y ahora aquí habríamos metido
00:27:52
esto directamente
00:27:54
esto si
00:27:56
queda bonito
00:28:07
vale, si ejecutamos esto
00:28:09
va a dar un error porque los stream
00:28:18
son
00:28:20
están muy bien, pero tienen alguna cosa
00:28:21
un poco pesada, y es que una vez que has recorrido
00:28:24
la fila, el stream se queda
00:28:27
inutilizable
00:28:29
no puedes reiniciarlo otra vez
00:28:30
entonces
00:28:32
tendríamos que volver a generarlo
00:28:34
no puedes reiniciarlo
00:28:36
entonces, veis ahora
00:28:38
si yo ejecuto esto
00:28:40
lo tengo aquí, ¿no?
00:28:41
¿cómo es que no me ha salido un error?
00:28:46
Ah, claro, me sale error porque es que la estoy generando otra
00:29:06
vez.
00:29:10
Claro, la estoy generando otra vez.
00:29:11
Pero si guardáis esto, el problema es que si lo guardáis
00:29:13
en un stream, el error os da así, ¿vale?
00:29:16
Imaginaos que generamos el stream.
00:29:19
El stream de íntegre.
00:29:24
Fila números, ¿vale?
00:29:29
Y lo generáis.
00:29:33
Y ahora ya usamos aquí fila números.
00:29:38
Y tratamos de volver a usar fila números otra vez
00:29:41
Es decir, el mismo stream
00:29:48
El mismo, de antes
00:29:49
Tratamos de volver a usar aquí fila números
00:29:50
Aquí sí me da un error
00:29:55
Porque el mismo stream, este mismo
00:30:00
Generado aquí
00:30:02
Si yo lo he recorrido una vez para hacer algo
00:30:02
Ya no lo puedo recorrer otra vez
00:30:05
Y no puedo reinicializar ese mismo stream
00:30:06
¿Vale? Aquí ya sí que da un error
00:30:08
Solo
00:30:11
¿Vale? El stream ya está cerrado
00:30:13
Claro
00:30:15
Por eso es por lo que normalmente en lugar de guardar el string, a crear el string y luego usarlo, lo voy creando cada vez que lo necesito.
00:30:16
O sea, se cierra automáticamente.
00:30:25
Se cierra automáticamente, se cierra automáticamente.
00:30:26
Entonces, en lugar de esta opción, es muchísimo mejor la opción que hemos escrito antes.
00:30:28
La que hemos puesto antes, que era esta.
00:30:36
Ah, si mejor
00:30:48
Cada vez que uso el stream
00:30:58
Lo genero de nuevas
00:31:00
Porque si no
00:31:00
¿Qué?
00:31:05
Te va a gustar
00:31:10
Que te va a acabar gustando, de verdad
00:31:12
Eso ya
00:31:14
No sé, depende de ti
00:31:20
Vale
00:31:22
Igual que esta for each
00:31:24
Esta filter
00:31:27
Por ejemplo
00:31:29
Por ejemplo, vamos a
00:31:30
Ay, ay, ya
00:31:32
Se me ha despertado
00:31:35
Vamos a, ahora
00:31:37
En lugar de mostrar el doble de todos ellos
00:31:38
Vamos a mostrar
00:31:41
Los pares
00:31:43
Por ejemplo
00:31:46
Vamos a mostrar los pares
00:31:47
Ahora sí que el programa serían
00:31:50
Tres líneas
00:31:53
Según la
00:31:54
La filosofía antigua
00:31:55
Y eso ya es mucho
00:31:59
Esto ya sí que sería muy feo, ¿verdad?
00:32:00
Bueno, vale
00:32:09
Puedes poner el operador condicional, lo que sea
00:32:10
Pero el operador condicional
00:32:12
Es muy angustioso
00:32:13
Sí, sí, está bien
00:32:15
Sí, pero es
00:32:19
Genera un poco de ansiedad
00:32:20
Porque te da afinaciones muy largas a veces
00:32:22
Vale
00:32:24
Pues esto sería mostrarlo
00:32:30
tú le enseñas esto
00:32:31
a alguien que lleve tiempo programando en Java
00:32:35
y te va a decir
00:32:37
vos no lo va a decir, pero lo va a pensar
00:32:39
va a pensar, va a decir
00:32:41
madre de Dios, vale, que patatero
00:32:42
es, ¿no? este chaval
00:32:45
hay gente que
00:32:46
sigue insistiendo en usar el stream
00:32:49
si no insistís
00:32:51
funciona
00:32:52
vale
00:32:53
pero seguramente, yo todo es
00:32:56
seguramente, porque yo no vivo ahí fuera
00:32:59
Vivo aquí dentro, pero bueno, intento
00:33:01
Más o menos en tratar de
00:33:03
De ilustrarme lo más posible
00:33:05
De cómo se vive fuera
00:33:07
Pero intuyo
00:33:08
Que si alguien ve este código
00:33:10
Pensaría, joder, vaya código patatero
00:33:14
Vale, ¿cómo lo podemos hacer?
00:33:16
Pues hombre
00:33:19
¿Qué es lo que estamos haciendo?
00:33:19
Estamos filtrando los pares
00:33:21
Para luego mostrarlos
00:33:24
Filtrar, filter, mostrar for each
00:33:25
Y le ponéis lo de arriba
00:33:28
Claro, pues vamos a hacer esto en una sola línea.
00:33:29
Enteros, punto stream.
00:33:35
Ya tenemos la filita.
00:33:37
Ahora, vamos a filtrar.
00:33:39
Ahora, si uno busca aquí los métodos para ver qué cosas
00:33:41
puede hacer, ve un filter que usa un predicado.
00:33:44
Porque el filter, el método filter,
00:33:50
si tú le pasas un predicado, lo que hace es ir uno por uno y a
00:33:52
A los que te den true, como resultado de ese predicado,
00:33:59
los que te den true los conserva en la fila
00:34:02
y a los que den false los tira a la basura.
00:34:05
Luego el filter se queda con los que dan true
00:34:08
en función del predicado que tú le pases.
00:34:10
Entonces podríamos pasarle este predicado de aquí,
00:34:15
que hace justo eso,
00:34:18
pero vamos a poner la función lambda directamente
00:34:20
porque es lo que haríamos en un caso real.
00:34:22
en un caso real
00:34:24
haríamos, oye, fíltrame
00:34:26
los pares, pues venga
00:34:28
te doy aquí mi predicado
00:34:30
aquí
00:34:32
ah, me lo dice por el punto y coma
00:34:35
vale, pero es que yo no quiero terminar todavía
00:34:40
ahora ya con la fila que me ha quedado
00:34:42
porque lo que normalmente hacemos
00:34:44
es ir anidando, anidando llamadas
00:34:46
aquí ahora tengo una filita más corta
00:34:48
tengo una fila solo con los pares
00:34:51
Y ahora, ¿qué quiero hacer con esa fila?
00:34:53
Con todos y cada uno quiero mostrarlo.
00:34:55
Pues venga, llamas al for each.
00:34:58
Y con el for each, ¿qué quieres hacer?
00:35:01
Pero voy a poner el for each aquí abajo para que se vea.
00:35:03
Claro, con el for each, ¿qué queremos hacer?
00:35:07
Pues con el for each queremos para cada x,
00:35:09
system.out.printlnx.
00:35:13
Pues en una sola línea estamos mostrando los pares.
00:35:25
Lo de arriba.
00:35:29
¿Vale?
00:35:32
Que ya sé que a ti no te gusta, Pablo.
00:35:33
¿Vale? Aquí, bueno, es difícil de ver porque no he puesto ni separadores ni nada.
00:35:42
Pero está mostrando los pares.
00:35:46
No lo creemos, ¿verdad?
00:35:48
Bueno, pues con estas líneas de código os tenéis que ir familiarizando.
00:35:59
que es una colección
00:36:04
le paso el string
00:36:06
y llamo a lo que necesite llamar
00:36:07
hasta aquí ninguna duda
00:36:09
¿no? vale, esto ya es
00:36:14
practicarlo y se acabó
00:36:15
aquí lo único, esto
00:36:17
esto en particular
00:36:19
este sistema
00:36:21
de X, no os lo vais a
00:36:23
encontrar escrito así nunca
00:36:26
entonces os digo
00:36:27
como os lo vais a encontrar escrito
00:36:30
y por qué se puede escribir así
00:36:31
para que no volváis locos.
00:36:33
A ver, ¿qué ocurre?
00:36:37
Pues ocurre lo siguiente.
00:36:39
Que cuando...
00:36:42
¿Ocurre qué?
00:36:43
Cuando una función lambda
00:36:48
lo que hace es llamar a un método estático
00:36:50
de una clase
00:36:53
pasando en el parámetro tal cual,
00:36:54
que es justo lo que está haciendo aquí.
00:36:58
println es un método
00:36:59
estático de system.out
00:37:02
y le estamos pasando el parámetro
00:37:04
de entrada tal cual
00:37:06
pues en esa situación, bueno y en alguna
00:37:07
otra, cuando llamamos también a
00:37:10
un método de instancia, también valdría
00:37:12
de esta propia x
00:37:14
pero bueno, eso lo podemos ver ahora
00:37:16
pero el caso más fácil de entender
00:37:18
cuando estamos llamando a un método
00:37:19
estático de una clase
00:37:22
y a ese método estático le estamos
00:37:24
pasando el parámetro
00:37:26
de entrada
00:37:28
se suele llamar entonces
00:37:28
al método
00:37:32
o se le suele escribir así
00:37:33
pongo la clase
00:37:35
para la que voy a llamar el método estático
00:37:38
esa clase es la que tiene
00:37:40
el método estático
00:37:42
pongo dos puntos
00:37:42
dos veces
00:37:46
dos puntos dos puntos
00:37:46
y ahora pongo
00:37:49
el nombre del método sin paréntesis
00:37:50
ni nada
00:37:53
entonces cuando Java
00:37:54
esto interpreta
00:37:57
que esto es el nombre de una clase
00:37:59
que esto es un método estático
00:38:01
de esa clase al que le pasas
00:38:05
el parámetro de entrada
00:38:07
es lo que interpreta
00:38:08
entonces es más cómodo de escribir
00:38:10
también podría ser
00:38:12
un método de instancia
00:38:15
de esta clase al que le pasas
00:38:17
el parámetro de entrada, pero se suele usar para métodos
00:38:19
estáticos
00:38:21
a ver
00:38:22
No, porque primero tenéis que...
00:38:31
A ver, yo no puedo contar esto en primero.
00:38:38
Claro que te voy a decir.
00:38:43
¿Se acuerda? Porque...
00:38:43
No, primero tenéis que...
00:38:45
Vale, a ver, ¿quién había dicho que no lo había entendido?
00:38:47
Vale, vale.
00:38:50
Este método, ¿vale?
00:38:52
Vale.
00:38:58
Este método, lo que tú estás haciendo aquí,
00:38:59
Es, estás llamando a un método estático de una clase, ¿verdad? Vale, es un método estático de esa clase. Bueno, y le estás pasando directamente el argumento de entrada, sin multiplicar por 2, sin dividirlo por 7, directamente el argumento de entrada.
00:39:01
ese es un caso muy particular que puede ser que tú
00:39:21
uses a veces dentro de tu función
00:39:24
pues si identificas
00:39:26
que estás haciendo eso
00:39:29
llamar a un método estático
00:39:30
de una clase
00:39:32
la que sea la clase y sea el que sea
00:39:34
el método estático
00:39:36
pasándole directamente el parámetro
00:39:37
sin modificar
00:39:40
puedes escribir esto de otra manera
00:39:42
que queda más claro
00:39:44
que es el nombre de la clase
00:39:45
la que sea
00:39:48
en este caso el asisten out
00:39:49
punto, punto, punto, punto
00:39:52
ahí seguidito
00:39:55
y después el nombre del método
00:39:56
sin paréntesis
00:39:58
la primera vez que ponemos
00:40:01
un método sin paréntesis no pasa nada
00:40:03
aquí se puede
00:40:05
y ya está
00:40:06
y ¿por qué no ponemos paréntesis?
00:40:08
porque se asume
00:40:11
en este caso
00:40:13
que el parámetro de entrada a este método
00:40:14
es este
00:40:17
se asume, no tienes que decirlo, se asume
00:40:18
si el parámetro de entrada
00:40:21
este método estático fuera otro
00:40:23
diferente a este, como este
00:40:25
multiplica por 7, no sé qué
00:40:27
pues no puedes llamarlo así, lo llamas
00:40:28
con la forma estándar y se acabó
00:40:31
¿vale?
00:40:32
entonces normalmente como el for each
00:40:34
se usa mucho para mostrar
00:40:37
los valores, para hacer comprobaciones
00:40:38
y mostrar por consola
00:40:40
este es un parámetro
00:40:42
típico que se le pasa al for each
00:40:44
Porque tú quieres hacer una comprobación de lo que hay en tu colección
00:40:46
Es un parámetro típico
00:40:48
Entonces, en lugar de
00:40:49
Encontraroslo así
00:40:52
Os lo encontraréis
00:40:54
Así
00:40:56
Y
00:41:00
Así
00:41:04
¿Vale?
00:41:08
¿Vale?
00:41:11
Entonces
00:41:16
No hay parámetro
00:41:16
De entrada en el lambda
00:41:19
¿Veis? Un segundito
00:41:20
¿Vosotros veis? Aquí una especificación de lambda
00:41:22
que tiene estos dos puntos raros.
00:41:25
¿Veis una especificación de lambda
00:41:30
con estos dos puntos raros?
00:41:31
Pues rápidamente asumís que
00:41:33
esto es una clase,
00:41:35
esto es un método estático de la clase
00:41:40
y a ese método estático
00:41:42
se le pasan
00:41:44
tal cual
00:41:46
los parámetros de entrada
00:41:48
que especifica esta interfaz.
00:41:50
En este caso, como es un for each
00:41:53
y el for each te pide un consumer,
00:41:55
Solo hay un parámetro de entrada.
00:41:57
Pero si esto no fuera un for it,
00:42:00
sino que fuera otro método,
00:42:02
que lo que le pasas es una bifunction, por ejemplo,
00:42:03
y le pasas un método estático,
00:42:08
también lo puedes especificar así,
00:42:11
sin poner los parámetros,
00:42:14
y se asume que a ese método estático
00:42:16
le pasas los dos parámetros.
00:42:17
¿Vale? Los dos parámetros.
00:42:21
Esto, por ejemplo, sí, dime.
00:42:25
todas las clases que tengan algún método estático
00:42:26
que reciba tantos parámetros
00:42:34
como esa interfaz funcional
00:42:36
si es consumer 1, si es bifunction 2
00:42:37
¿vale? funciona con cualquier método estático
00:42:40
¿vale? pues
00:42:44
¿eh?
00:42:54
¿perdón?
00:43:08
Sí, sí, sí, está todo grabado
00:43:09
Lo que pasa es que
00:43:11
Lo que pinto aquí
00:43:12
No se graba ahí, pero bueno
00:43:15
Vale, entonces
00:43:16
Por ejemplo, para cerrar esto ya
00:43:18
Otro método
00:43:21
Que se suele usar mucho
00:43:26
De stream
00:43:28
El map
00:43:31
El map
00:43:34
Usa una función
00:43:36
El map lo que te hace es
00:43:37
Cada elemento de tu filita
00:43:39
Te lo transforma en otro
00:43:41
Por ejemplo, vamos a hacer un código que te construya, que te transforme al map, tendríamos que pasarle una lambda que te transforme cada numerito entero,
00:43:43
Que te lo transforme
00:44:09
En su
00:44:13
Factorial, vamos a complicarnos la vida
00:44:18
Lo podemos hacer aparte
00:44:20
Y antes de ya dejarlo
00:44:22
Pero vamos a parar, ¿vale?
00:44:23
Que son y 20
00:44:25
- 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:
- 13
- Fecha:
- 24 de septiembre de 2025 - 18:04
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 44′ 30″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 182.27 MBytes