Saltar navegación

20250923-InterfacesFuncionales_2 - 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 24 de septiembre de 2025 por Raquel G.

13 visualizaciones

Descargar la transcripción

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
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
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
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
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
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

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid