Saltar navegación

20260428 InterfacesFuncionales_Lambdas - 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 29 de abril de 2026 por Raquel G.

9 visualizaciones

Descargar la transcripción

Siento un poco de presión 00:00:00
Vale, ahora ya le he dado 00:00:04
¿Ya estás contento? 00:00:09
Venga, pues entonces 00:00:14
Pizarrita 00:00:15
Vale, pues veréis qué precioso es esto 00:00:19
Realmente 00:00:22
Y cómo cambia la visión de las cosas 00:00:22
Vale, pues a ver 00:00:25
Imaginad 00:00:36
Para motivar 00:00:37
La existencia de todo esto 00:00:39
Imaginad, por ejemplo, que estamos haciendo 00:00:41
una clase calculadora para variar 00:00:43
que es la más 00:00:45
ocurrida porque tiene varias 00:00:46
operaciones, varias cosas que 00:00:49
hacer muy parecidas entre sí, como sumar, restar 00:00:51
multiplicar, bueno pues imaginar 00:00:53
que vamos a hacer ahí una calculadora 00:00:55
entonces 00:00:58
tenemos varias operaciones 00:01:07
por ejemplo vamos a quedarnos con sumar y multiplicar 00:01:09
que es lo más sencillo 00:01:12
pues uno haría, venga pues que puede hacer mi calculadora 00:01:13
mi calculadora 00:01:16
puede sumar 00:01:17
pues venga yo me hago 00:01:19
mi primer método 00:01:20
me hago mi primer método 00:01:22
sumar 00:01:35
pues donde le paso los operandos 00:01:37
y aquí 00:01:40
le digo pues nada, return 00:01:48
pues los operandos pueden estar aquí 00:01:51
vale, hasta aquí bien 00:01:55
un método de toda la vida al que le pasamos datos 00:02:04
porque hasta ahora hemos hablado 00:02:06
de que a los métodos les pasamos datos 00:02:08
vale, que le pasamos datos 00:02:11
ahora yo quiero restar 00:02:13
o multiplicar 00:02:14
pues ese método no es igual que este 00:02:16
porque no hace lo mismo 00:02:19
entonces yo aquí haría 00:02:20
pues mi otro método 00:02:23
donde ya este otro método 00:02:24
muy parecido pero no es igual 00:02:37
porque este método me haría esto 00:02:38
por ejemplo 00:02:41
entonces tengo dos métodos distintos 00:02:42
para hacer dos operaciones distintas 00:02:45
muy parecidos entre sí 00:02:47
entonces aquí uno podría 00:02:48
dar ya el primer salto 00:02:50
para 00:02:53
colocar o refactorizar este código 00:02:53
que es, vamos a ver 00:02:57
estos dos métodos solamente 00:02:58
se diferencian en esta cosita de aquí 00:03:01
solo en esto 00:03:03
bueno, pues los voy a meter 00:03:05
en un solo método, por ejemplo, que sea 00:03:07
operar 00:03:09
y yo le paso, aparte de mis datos 00:03:10
le paso la operación de alguna manera 00:03:13
ya veré cómo, le paso la operación 00:03:16
de alguna manera, si es suma si es resta 00:03:18
y en función de la operación que la haga unir 00:03:20
¿vale? bueno, pues sería el primer paso 00:03:22
para a lo mejor cambiar esto un poquito 00:03:24
y que no empezaran a proliferar 00:03:26
ahí propiciando métodos 00:03:28
sumar, multiplicar, restar, dividir 00:03:30
no sé qué, no sé cuántos 00:03:32
sería lo ideal, que esto no proliferara 00:03:33
bueno, pues entonces 00:03:36
podríamos hacer 00:03:38
esa primera 00:03:40
la refactorización y decir, pues ala, voy a llamar a mi método operar, operar, que 00:03:42
es lo que hace una calculadora, la calculadora opera, a mi método le llamo operar y ahora 00:03:54
le tengo que pasar, si no tengo los operandos aquí, eso ya depende de cómo haya hecho 00:04:01
el diseño, pues a lo mejor 00:04:07
le tengo que pasar los operandos 00:04:09
necesito un dato más, si o si 00:04:15
necesito un dato más que es 00:04:17
que tipo de operación, para que 00:04:19
en función del tipo de operación haga una cosa 00:04:21
u otra, entonces yo aquí tengo que tomar 00:04:23
una decisión y es 00:04:25
el tipo de operación como lo convierto 00:04:26
a dato, bueno en este caso 00:04:29
a lo mejor lo podría hacer 00:04:31
como un string, le paso 00:04:32
un string con el más o con el menos 00:04:35
o con el por, entonces he hecho ya una cosa 00:04:37
que es medio rara, convertir 00:04:39
una operación en un 00:04:41
dato y para eso me he 00:04:43
inventado, he decidido 00:04:45
que se la voy a pasar en un string 00:04:46
¿vale? 00:04:48
entonces ahora yo aquí 00:04:51
tendría que hacer mi shift, el save 00:04:52
en función de 00:04:55
la operación, si ese 00:04:57
dato operaciones suma 00:04:59
hago lo que sea, si ese dato 00:05:00
operación es resta hago lo que 00:05:02
sea, etc. 00:05:05
pues nada, esto sería otro 00:05:07
planteamiento, que sigue los principios de la programación declarativa de toda la vida. 00:05:09
Pero, teniendo en cuenta que esto es una operación, este dato de aquí que yo le paso es una operación, 00:05:26
podríamos decir, vamos a ver 00:05:49
yo a este tío 00:05:52
a este método 00:05:54
lo que le tengo que decir es 00:05:55
que tiene que hacer 00:05:58
eso es lo que le tengo que decir 00:05:59
si tiene que sumar, si tiene que restar 00:06:01
si tiene que multiplicar, eso es lo que le tengo que decir 00:06:04
que tiene que hacer 00:06:06
luego, lo que realmente le tengo que pasar 00:06:07
a este método es 00:06:10
una acción 00:06:12
un comportamiento, es lo que le tengo que pasar 00:06:14
le tengo que pasar, no unos datos 00:06:16
lo que le tengo que pasar es 00:06:18
oye, haz esto 00:06:20
le tengo que pasar la acción que tiene que hacer 00:06:22
lo que tiene que hacer 00:06:24
le tengo que decir, tú tienes que hacer esto 00:06:25
incluso 00:06:28
con toda la secuencia de instrucciones 00:06:29
tú lo que tienes que hacer es coger unos datos 00:06:31
sumarlos, mostrarlos 00:06:33
incluso le puedo pasar 00:06:35
sería ideal que yo le pudiera 00:06:38
pasar por parámetro 00:06:40
una lista de todo lo que tiene que hacer 00:06:41
una lista de órdenes 00:06:43
sería como a un método 00:06:44
pasarle como parámetro otro método 00:06:47
¿vale? que es algo 00:06:50
distinto a lo que hemos hecho siempre 00:06:51
a un método siempre le hemos pasado 00:06:53
por parámetro datos, punto pelota 00:06:55
datos, y normalmente siempre 00:06:58
en general, pues esa es la idea 00:07:00
con la que programamos, a un método se le pasan 00:07:01
datos, ese método 00:07:03
coge datos y opera 00:07:05
con ellos y me da resultados 00:07:08
vale, pues la programación funcional 00:07:09
te dice, oye 00:07:12
¿y por qué no un comportamiento 00:07:13
o lo que es lo mismo una lista de acciones 00:07:15
porque eso no podría ser también 00:07:17
un dato que pasarle a otro 00:07:20
es decir 00:07:23
yo le puedo pasar a un método 00:07:25
una lista de cosas que tiene que hacer 00:07:28
como si le pasara a otro método 00:07:30
pues ese es el principio básico de la programación funcional 00:07:32
que es una función, una lista de acciones 00:07:37
un método, una lista de cosas 00:07:40
también se puede ver como un dato 00:07:42
también se puede ver como un dato 00:07:44
y ese dato se lo puedo yo pasar 00:07:46
a otro método 00:07:48
y ese otro método 00:07:49
usa eso 00:07:51
que yo le he pasado ahí 00:07:53
y hace lo que yo le he pasado aquí 00:07:55
esa es la idea 00:07:58
ahora hay que ver cómo se concreta 00:07:59
eso en Java 00:08:02
que es parecido a cualquier otro lenguaje 00:08:03
pero la idea tiene que quedar clara 00:08:06
que es una lista de acciones 00:08:08
lo que para nosotros 00:08:10
ha sido un método de toda la vida 00:08:12
y lo que en general se llama función 00:08:13
una lista de acciones tenemos que poder verla 00:08:15
también como un posible dato 00:08:18
todo él, un posible dato 00:08:20
y como tal 00:08:21
lo puedo yo pasar también como argumentos a métodos 00:08:23
¿vale? 00:08:26
entonces 00:08:29
a un método le puedo pasar 00:08:29
los datos de toda la vida 00:08:31
un número, una cadena 00:08:33
un objeto, los datos de toda la vida 00:08:36
pero también le puedo pasar 00:08:38
una lista de acciones 00:08:39
también le puedo pasar una lista de acciones 00:08:41
se abre un poco la filosofía 00:08:43
bueno, pues esa sería la idea 00:08:46
ahora, ¿cómo se concreta? 00:08:49
vamos a intentar 00:08:51
verlo de forma sencilla 00:08:52
en un ejemplo sencillo 00:08:56
a ver, bueno 00:08:58
esto vamos a verlo ya 00:08:59
en la pizarra 00:09:01
en la esta, que se va a entender mejor 00:09:08
vale, bueno, lo que he dicho 00:09:10
hasta ahora 00:09:18
aunque nos cueste 00:09:19
de alguna manera a ver cómo se puede concretar eso 00:09:22
de meter una lista de acciones 00:09:24
como dato 00:09:26
aunque nos cueste, entendemos la idea 00:09:28
vale, vamos a ver cómo se concreta 00:09:30
esto, a ver 00:09:32
pues venga 00:09:33
me voy a hacer aquí 00:09:36
borro todo esto 00:09:39
pues venga, me hago un proyecto normal y corriente 00:09:41
no, porque no vamos a usar dependencias ni nada 00:09:46
ejemplo 00:09:52
interfaces funcionales 00:09:56
vale 00:09:59
bueno pues entonces lo primero que tenemos que pensar 00:10:00
vale 00:10:08
donde 00:10:10
si yo tengo que meter 00:10:12
toda una serie de acciones 00:10:13
toda una serie de acciones en un 00:10:15
dato de que 00:10:18
tipo va a ser ese dato 00:10:20
porque una cadena ya sabemos que va 00:10:21
a un string, un número 00:10:24
ya sabemos que va a un integer, a un double 00:10:26
depende de lo que sea 00:10:28
un objeto alumno, ya sabemos que va a la clase alumno 00:10:29
que alguien habrá declarado, pero 00:10:33
y un conjunto de instrucciones, eso a qué tipo 00:10:35
de objeto va, porque si es un dato también como tal 00:10:39
tendrá que ser declarado de una clase también 00:10:42
si estamos diciendo que una serie de instrucciones 00:10:44
también puede ser tratada como dato 00:10:48
pues también tiene que poder pertenecer a alguna clase 00:10:51
porque todos los datos pertenecen a clases, sea inter, sea alumno 00:10:54
sea la que sea, pues a qué clase 00:10:57
pertenece un montón de 00:10:59
sentencias, bueno pues 00:11:01
pertenece a 00:11:03
algo que se ha tenido que programar como una 00:11:04
cosa que se llama interfaz funcional 00:11:07
las interfaces 00:11:09
sabéis lo que son 00:11:11
son clases con métodos vacíos 00:11:12
esencialmente es eso, con métodos vacíos 00:11:15
que están pensadas para que la gente las 00:11:17
implemente y ya 00:11:19
de cuerpo esos métodos 00:11:21
vale, pues no vamos a hacer una interfaz con un método vacío 00:11:22
venga, nos hacemos 00:11:25
una interfaz con un método vacío, vale, pues esta interfaz 00:11:34
se va a llamar operar, vale, porque estamos ligando 00:11:39
con el ejemplo este nuestro de calculadora, en el cual 00:11:44
lo que le queremos pasar a nuestra calculadora es una serie 00:11:47
de instrucciones que tiene que hacer en el método suyo operar, 00:11:51
el que sea, entonces esa serie de instrucciones que van a ser 00:11:54
la operación que tiene que hacer, la queremos guardar 00:11:58
como objeto, tendremos que declarar 00:12:02
una clase, bueno, pues entonces 00:12:04
yo me declaro una interfaz 00:12:06
que la voy a llamar 00:12:08
operar 00:12:10
vale, a ver, como no he puesto 00:12:10
un paquete, perdón 00:12:13
vale, pues yo que sé, ahora ya sí 00:12:15
me hago mi interfaz 00:12:24
operar 00:12:25
vale, entonces 00:12:27
a esta 00:12:36
interfaz le voy a poner un método 00:12:37
vacío, abierto 00:12:40
por ejemplo este 00:12:41
opera 00:12:44
un método vacío 00:12:47
bueno 00:13:02
pues resulta 00:13:06
que una interfaz 00:13:09
que tiene un único 00:13:10
método 00:13:13
sin declarar 00:13:14
es lo que se llama una interfaz funcional 00:13:16
vale 00:13:19
si esta interfaz tuviera más 00:13:21
métodos vacíos 00:13:23
sería una interfaz normal y corriente 00:13:24
pero no sería una interfaz funcional, es el primer 00:13:26
punto, ahora veremos para qué me 00:13:28
sirve que sea funcional y para qué no me sirve 00:13:30
¿vale? 00:13:32
entonces 00:13:35
una interfaz aparte de 00:13:35
métodos vacíos, uno o muchos 00:13:38
si recordáis 00:13:40
de interfaces, puede tener 00:13:41
métodos con declaraciones por defecto 00:13:44
los que tiene el default 00:13:47
delante, ¿vale? una interfaz 00:13:48
podría tener 00:13:50
un método 00:13:52
¿no? pues yo que 00:13:54
ser cualquier cosa, un método 00:13:56
cualquiera 00:13:58
que hiciera cualquier cosa 00:13:59
vale, esto también lo 00:14:02
admitían las interfaces 00:14:14
también lo admitían, implementaciones por 00:14:15
defecto, vale 00:14:18
entonces esta seguiría siendo una interfaz 00:14:19
funcional, porque sólo 00:14:22
tiene un método abierto 00:14:24
vacío, sólo tiene uno 00:14:26
esta seguiría siendo una interfaz funcional 00:14:27
vale, puede tener muchas 00:14:29
implementaciones por defecto de otros 00:14:32
o puede tener métodos estáticos 00:14:34
recordad que las interfaces también pueden tener 00:14:36
métodos estáticos 00:14:38
¿vale? que el uso 00:14:39
es, pues yo meto ahí código 00:14:42
relacionado con el concepto que se llama 00:14:44
interfaz y lo puedo llamar directamente con el nombre 00:14:46
de interfaz, operar punto, ese método estático 00:14:48
y ya está, los métodos estáticos 00:14:50
sí que tienen que tener cuerpo obligatorio 00:14:52
¿vale? en las interfaces 00:14:54
bueno, pues entonces, tenga lo que 00:14:55
tenga, este que no me sirve 00:14:59
para nada lo quito, tenga lo que tenga 00:15:01
si la interfaz que yo he hecho tiene un único 00:15:02
método vacío, como es el caso 00:15:04
se convierte en interfaz funcional 00:15:06
muy bien, vale, pues ya está 00:15:08
hasta ahora lo único que hemos hecho es cambiarle 00:15:10
la etiqueta, el nombre, se llama interfaz funcional 00:15:12
mira, pues que bien, se llama interfaz funcional 00:15:14
vale 00:15:16
aunque no es obligatorio 00:15:17
a las interfaces funcionales 00:15:20
conviene anotarlas 00:15:23
con esta 00:15:25
anotación 00:15:27
la he escrito mal, funcional 00:15:28
interface 00:15:37
ahora está bien escrita, vale 00:15:39
no es obligatorio 00:15:40
lo que pasa es que en mi aplicación 00:15:42
las que yo tenga como funcionales 00:15:46
que las tendré por alguna razón en particular 00:15:47
si las tengo anotadas mejor 00:15:49
le estoy dando más 00:15:51
más descripción 00:15:53
a toda mi aplicación 00:15:56
aparte tiene otra ventaja, anotarla 00:15:57
que si yo de repente me equivoco 00:15:59
estoy cambiando código, refactorizando código 00:16:02
me equivoco 00:16:04
y pongo aquí otro método vacío 00:16:05
automáticamente se me va a poner esto en rojo 00:16:07
Porque va a decir, oye, tú no eres una interfaz funcional 00:16:10
Si yo me equivoco y pongo aquí otro método cualquiera 00:16:13
Porque me he equivocado 00:16:16
Pues automáticamente me salta el compilador 00:16:17
Y me dice, perdona, me acabas de decir que tú eres una interfaz funcional 00:16:21
Te has comprometido a ello 00:16:25
No te pongas a plantar otros métodos 00:16:27
Sin embargo, si yo no hubiera puesto esta anotación 00:16:30
Aquí el compilador no me avisa 00:16:33
Y a lo mejor yo he puesto este segundo método porque me he equivocado 00:16:36
y no tengo ese primer 00:16:39
aviso del compilador. 00:16:41
¿Vale? 00:16:43
Y puede ser que yo sí que necesite 00:16:44
que sea funcional. ¿Por qué? Pues por lo que vamos a ver 00:16:46
ahora. Vale, pues bueno. 00:16:48
Si tienes el default delante, 00:16:55
sí. Si no, no. 00:16:57
¿Vale? Da una 00:16:59
implementación por defecto para esos métodos. 00:17:03
Y si las clases que implementan la interfaz 00:17:06
no lo sobrescriben, se quedarían con 00:17:08
esa implementación por defecto. 00:17:10
Muy peligroso que haya 00:17:12
métodos default en las interfaces, porque 00:17:13
le estás dando comportamiento a gente 00:17:16
que te implementa que a lo mejor no lo 00:17:18
quieren. Entonces 00:17:20
es algo muy peligroso 00:17:21
porque en una aplicación grande de repente 00:17:23
tú incorporas una entidad nueva 00:17:25
que implemente esa interfaz 00:17:27
y te has quedado con todos 00:17:29
sus defaults y realmente no 00:17:31
sabes que tiene ahí. Entonces vete a 00:17:33
saber el efecto secundario que puede generar 00:17:35
eso. Entonces los defaults se ponen 00:17:37
solo cuando realmente se 00:17:39
sabe que eso no va a perjudicar 00:17:41
a ampliaciones de la aplicación ni a nada. 00:17:43
Bueno, pues en nuestro caso, esta es nuestra interfaz funcional, vale, ahora, pues esta es la clase a la que ahora puede pertenecer cualquier tipo de sentencias que signifiquen opera, es decir, yo ahora puedo hacer sumas, restas, multiplicaciones, lo que yo quiera, todo el código que quiera, 00:17:46
y todo ese código 00:18:11
lo voy a poder declarar 00:18:13
de la clase operar 00:18:15
¿cómo? vamos a verlo 00:18:17
¿vale? pero repito 00:18:19
el haber declarado esta 00:18:22
interfaz funcional me permite 00:18:25
ahora 00:18:27
meter un método 00:18:27
meter sentencias 00:18:31
como dato 00:18:32
y su tipo de dato va a ser 00:18:34
el tipo de dato operar 00:18:37
vamos a verlo ahora 00:18:38
entonces me voy a hacer aquí 00:18:41
yo que sé, un main, vale 00:18:42
pues resulta que yo quiero definir 00:19:06
una operación 00:19:08
pero la quiero definir como dato 00:19:09
es decir 00:19:12
quiero un conjunto de sentencias 00:19:14
meterlas como dato 00:19:16
para que se queden ahí como dato, para pasarlas 00:19:18
luego a otro sitio 00:19:20
vale, pues ese conjunto de sentencias 00:19:21
las voy a poder meter 00:19:24
como dato 00:19:26
imaginaos que hay en secuencia 00:19:27
operaciones 00:19:31
las voy a poder meter 00:19:31
como dato en un objeto 00:19:34
de este tipo, del tipo 00:19:36
interfaz funcional que está aquí 00:19:38
y ahora la pregunta sería 00:19:39
vale, muy bien, ya tengo un objeto 00:19:45
declarado del tipo operar 00:19:47
este objeto 00:19:49
no está pensado para 00:19:51
contener datos como tal 00:19:53
no está pensado para contener números 00:19:54
cadenas, no 00:19:57
este objeto 00:19:58
por pertenecer a una clase 00:20:00
interfaz funcional 00:20:02
está pensado para 00:20:04
contener una secuencia de acciones 00:20:05
ahora 00:20:08
¿qué secuencia de acciones? 00:20:09
se definen en la instanciación 00:20:11
entonces 00:20:13
aquí uno diría 00:20:15
vale, pero espérate 00:20:18
¿cómo instancio yo esto? no puedo hacer 00:20:19
un new operar, porque operar 00:20:21
es una interfaz y las interfaces ya sabemos 00:20:23
que no se pueden instanciar, no tienen 00:20:25
constructores, ¿cómo instancio 00:20:27
yo ese objeto y le doy 00:20:29
su valor? que su valor 00:20:31
va a ser toda una lista de sentencias 00:20:33
hemos quedado, bueno pues entonces 00:20:35
¿qué tengo que hacer yo? 00:20:37
pues antes de instanciarlo 00:20:39
tenemos que crearnos 00:20:41
una clase 00:20:43
que implemente esta 00:20:45
y que ahora ya 00:20:46
meta ese conjunto de sentencias 00:20:48
en la implementación 00:20:51
de este método 00:20:54
es decir 00:20:54
vamos ahora a crearme yo 00:20:57
una clase aquí 00:20:59
por ejemplo sumar 00:21:00
Porque yo ahora quiero implementar esa lista de operaciones como sumar. 00:21:04
Pues venga, new, me hago una clase, sumar. 00:21:10
Esta clase sumar implementa, implements, operar. 00:21:19
Vale, al implementar operar no le queda más remedio que implementar el método que tiene la interfaz funcional, el único que tiene. 00:21:31
Ahí viene la importancia de que sea solo uno. 00:21:40
Bueno, pues es aquí, es aquí, donde yo ya decido qué sentencias quiero que se metan en el objeto que voy a instanciar aquí. 00:21:44
Esto es un poco lio, pero lo repetimos. 00:21:59
Venga, pues a ver, ¿qué quiero yo hacer en este objeto? 00:22:02
Pues lo que yo quiero hacer es sumar, es solo una sentencia, podrían ser mil, pero es solo una. 00:22:05
Retuno operación 1, 1 más operación 2. 00:22:12
Podría ser un código mucho más largo 00:22:16
¿Vale? Podría ser un código larguísimo 00:22:19
Vale, pues ahora que ya tengo esta clase 00:22:20
Yo ahora ya puedo hacer esto 00:22:34
Igual a new 00:22:35
Sumar 00:22:38
Esto ya lo puedo hacer 00:22:40
¿Verdad? Porque sumar 00:22:42
Implemento a operar, luego esto 00:22:47
Esta línea 00:22:49
Ahora mismo es como hemos hecho siempre 00:22:50
Pero no nos han gustado 00:22:53
¿Vale? ¿Pero qué es lo que hay debajo de esto? 00:22:54
Pues lo que hay debajo de esto 00:22:58
es lo que es realmente importante 00:22:59
porque ahora nos va a permitir usarlo 00:23:01
y es, lo que hay debajo de esto es 00:23:03
oye, este objeto 00:23:05
es un dato en realidad 00:23:07
es un dato, porque es un dato que 00:23:09
pertenece a una clase, es un dato 00:23:11
pero que tiene dentro 00:23:12
este dato, no tiene 00:23:15
dentro números 00:23:17
cadenas 00:23:19
como un alumno que tiene número de matrícula 00:23:21
profesores, no 00:23:24
lo que tiene dentro este dato 00:23:25
es esto 00:23:27
lo que yo haya puesto en este método 00:23:29
eso es lo que tiene 00:23:31
luego 00:23:33
cualquier dato que uno declare 00:23:35
cuyo tipo de datos 00:23:37
sea una interfaz funcional 00:23:39
no tiene dentro datos como los entendemos 00:23:40
hasta ahora 00:23:43
pues color de ojos 00:23:44
altura, no sé qué 00:23:48
no tiene datos como entendemos hasta ahora 00:23:49
cualquier objeto declarado 00:23:51
como una interfaz funcional 00:23:53
lo que tiene dentro es 00:23:54
una lista de sentencias 00:23:56
que en ese caso son las sentencias 00:23:59
que están implementando 00:24:01
el único método 00:24:03
que este tiene vacío 00:24:05
de ahí la importancia de que 00:24:06
solo haya un método vacío en la interfaz 00:24:09
funcional, porque en ese único método 00:24:11
vacío es donde se van 00:24:13
a implementar esas instrucciones 00:24:15
que son las que son el verdadero 00:24:17
dato, el verdadero 00:24:19
dato de este objeto 00:24:21
¿vale? 00:24:22
entonces este objeto es de tipo operar 00:24:24
luego automáticamente como operar es una 00:24:26
interfaz funcional, tenemos que verlo 00:24:29
como que no es un dato cualquiera 00:24:30
sino que es una secuencia de instrucciones 00:24:32
vale, esa secuencia 00:24:34
de instrucciones de donde sale 00:24:37
de la implementación que yo he usado para 00:24:38
generarlo, la implementación 00:24:40
que yo he usado para generarlo es sumar 00:24:43
que tiene sumar, tiene esto 00:24:44
vale, muy bien 00:24:47
vale, entonces podría haber otra implementación 00:24:48
por ejemplo, vamos a hacernos multiplicar 00:24:53
Nos hacemos aquí 00:24:55
Una nueva clase 00:24:57
Multiplicar 00:25:01
Vale 00:25:04
Multiplicar va a ser 00:25:05
Otra posible implementación 00:25:08
De mi interfaz funcional 00:25:10
Implements 00:25:11
Multiplicar implementa operar 00:25:13
Al implementar 00:25:16
Operar tiene que implementar el método 00:25:19
Bueno pues aquí lo que a mi me de la gana 00:25:20
En este caso 00:25:25
pues es una sola sentencia 00:25:27
podría ser mil 00:25:29
retuno op1 00:25:30
por op2 00:25:33
ala tan ricamente 00:25:34
entonces podría tener 00:25:36
vale 00:25:39
multiplicar ha implementado eso 00:25:41
ahora ya en mi main por ejemplo 00:25:42
secuencia suma voy a poner 00:25:45
aquí operar suma la voy a cambiar 00:25:47
a llamar suma 00:25:49
operar suma 00:25:50
pues voy a hacerme otro 00:25:53
operar multiplica 00:25:54
igual a new multiplicar 00:25:57
vale, pues estos son 00:26:05
dos objetos, el objeto suma 00:26:10
y el objeto multiplica 00:26:12
¿qué es lo que tienen dentro esos objetos? 00:26:14
¿cuál es su dato? 00:26:17
pues el objeto suma 00:26:18
lo que tiene dentro es 00:26:19
esta secuencia de instrucciones 00:26:21
esa es la que tiene dentro 00:26:25
¿qué tiene dentro el objeto multiplica? 00:26:26
pues lo que tiene dentro el objeto 00:26:31
multiplica es 00:26:32
esta lista de instrucciones, es lo que tiene dentro 00:26:33
¿vale? 00:26:36
luego ya hemos hecho la primera parte 00:26:37
que es crear objetos 00:26:39
que lo que tienen dentro son secuencias 00:26:41
de instrucciones, no datos como tal 00:26:44
ahora habría que ver esto para que me sirve, como lo puedo usar 00:26:46
bueno, vámonos a nuestra calculadora 00:26:50
lo estoy haciendo todo en el main 00:26:59
por facilidad 00:27:04
nuestra calculadora 00:27:05
me hago yo ahora aquí 00:27:08
mi clase calculadora 00:27:10
calculadora 00:27:11
vale, mi clase calculadora va a operar 00:27:14
vale, pues que le voy a pasar 00:27:21
yo a mi calculadora, le voy a pasar directamente 00:27:28
lo que tienes que hacer, no le paso los datos 00:27:31
la operación en forma de string 00:27:34
y luego ella lo saca de dentro y ya se pone a hacer cosas 00:27:37
no, te paso la operación 00:27:40
tal cual, vale, luego te voy a pasar 00:27:43
algún objeto de tipo operar 00:27:46
Esto es lo que te voy a pasar 00:27:48
¿Vale? 00:27:50
Algún objeto de tipo operar 00:27:52
¿Y tú qué vas a hacer? 00:27:54
Pues vas a llamar al método 00:27:58
Opera 00:28:00
De eso de ahí 00:28:00
¿Vale? Y me lo vas a devolver 00:28:03
A ver 00:28:06
¿Cómo se lo podemos pasar? 00:28:18
Opera 00:28:21
¿Vale? Pues entonces 00:28:22
Aunque en este caso 00:28:59
realmente era tan fácil como pasarle 00:29:00
el simbolito y que con el símbolo decidiera 00:29:03
con el if, con el else if 00:29:05
pues es que 00:29:06
ni siquiera hace falta 00:29:08
yo llamo, mi calculadora tiene operar 00:29:10
y le paso directamente 00:29:12
la secuencia que tiene 00:29:15
que hacer, se lo paso directamente 00:29:17
le pasaría un objeto de tipo 00:29:18
operar 00:29:21
el que sea, y ese objeto llamará 00:29:21
a opera, que tendrá lo que sea 00:29:25
estellará lo que sea con estos operandos 00:29:28
entonces mi calculadora ahora cambiará 00:29:30
y se declarará de esta manera 00:29:35
¿vale? se declarará así 00:29:37
y ahora 00:29:39
¿cómo la uso yo? 00:29:41
pues a ver este como 00:29:44
vamos a ponerlo 00:29:45
static, como los operandos se los estamos 00:29:47
pasando, le ponemos 00:29:49
static y ahora ya en mi 00:29:51
main ¿vale? 00:29:53
pues yo podría hacer por ejemplo 00:29:55
calculadora 00:29:57
punto opera 00:30:00
le paso el objeto suma 00:30:03
este 00:30:06
y los operandos que sean 00:30:07
que ahora 00:30:10
quiero hacer una multiplicación 00:30:20
operar 00:30:24
le paso 00:30:27
el objeto multiplica 00:30:29
y lo que sea 00:30:31
vale pues entonces 00:30:35
mi calculadora 00:31:12
está recibiendo dos datos estándar 00:31:13
los de toda la vida, dos numeritos 00:31:15
como podían ser cadenas, lo que fuera 00:31:17
y además está recibiendo un objeto 00:31:19
que lo que tiene dentro 00:31:22
en realidad es 00:31:24
toda una ristra de operaciones 00:31:25
que en mi caso esa ristra 00:31:27
en el caso de suma 00:31:29
que sería este objeto 00:31:31
esa ristra se reduce a esto 00:31:32
y en el caso de 00:31:35
este de aquí 00:31:39
multiplica, lo que yo le estoy pasando 00:31:40
solamente esto 00:31:44
op1 por op2 00:31:46
pero lo que tenéis que ver 00:31:48
en este ejemplo sencillo 00:31:50
es que yo aquí a este método 00:31:51
le estoy pasando 00:31:54
de estos tres datos 00:31:55
uno de ellos 00:31:58
es un dato especial, porque uno de ellos 00:32:00
no contiene cadenas, números 00:32:02
objetos de toda la vida 00:32:04
con propiedades dentro, no 00:32:06
uno de ellos 00:32:08
este lo que tiene es una secuencia 00:32:10
de operaciones, no tiene datos 00:32:12
tiene secuencia de operaciones 00:32:14
luego la secuencia de operaciones 00:32:16
también se pueden 00:32:19
pasar como parámetro 00:32:21
y esa es la idea de la programación funcional 00:32:22
que se puede 00:32:24
que se integra en el diseño de cualquier aplicación 00:32:29
en realidad, vale, esa sería 00:32:32
la primera parte, lo que quería 00:32:35
que 00:32:37
entiendo que no es fácil, es lioso 00:32:38
porque implica 00:32:42
muchos pasos 00:32:44
tiene que existir una interfaz funcional 00:32:45
obligatorio, con un método vacío 00:32:47
en ese método vacío 00:32:49
es donde en sus implementaciones 00:32:52
en las implementaciones 00:32:54
en todas las que haya, que pueda haber 00:32:56
mil implementaciones distintas de operar 00:32:57
pues en las implementaciones 00:32:59
de operar, en las instancias 00:33:02
de operar, es donde irá 00:33:03
todo ese conjunto de sentencias 00:33:05
que es el propio dato, el conjunto de sentencias 00:33:07
en las una, dos, tres 00:33:10
diez mil implementaciones de operar 00:33:12
que yo quiera hacer, en cada una de ellas irá 00:33:14
un conjunto de sentencias 00:33:15
Y ese conjunto de sentencias es el dato. Y ahora yo ya, en esa implementación que he puesto ese conjunto de sentencias, una, dos o mil, este método podría ser muy largo, pues ese dato, que es este, esto ahora ya es, repito, esto es un conjunto de sentencias, no es un objeto normal. 00:33:17
Es un conjunto de sentencias, este el conjunto de sentencias que están dentro de sumar y este el conjunto de sentencias que están dentro de multiplicar, pues estos dos conjuntos de sentencias pueden ser pasados a cualquier otro método, pueden ser pasados a cualquier otro. 00:33:40
y ahora ese método 00:33:57
que hará aquí el de calculadora 00:34:01
en particular, pues claro, ese método 00:34:03
lo que tiene que hacer es lógicamente 00:34:05
llamar 00:34:06
al método de la interfaz funcional 00:34:07
claro, lo llama y actúa 00:34:10
bueno, esta es 00:34:13
la idea 00:34:17
de la interfaz funcional y la motivación 00:34:18
la arquitectura, ¿está más o menos 00:34:20
claro y entendido? 00:34:23
y ahora diréis, ¿y esto que tiene que ver con las 00:34:25
landas? pues porque 00:34:27
una lambda es una forma rápida 00:34:29
de hacer una 00:34:31
implementación, una instancia 00:34:33
de una interfaz funcional, ahorrándose 00:34:35
este paso que yo he hecho aquí 00:34:37
que es declarando esta clase 00:34:38
es decir, yo para crear 00:34:40
aquí una instancia 00:34:43
de operar adaptada a mis 00:34:44
necesidades 00:34:47
porque yo quería, oye quiero una instancia 00:34:47
de operar que lo que haga sea sumar 00:34:51
pues para crear una instancia de operar 00:34:52
me he hecho una clase sumar 00:34:55
que lo implemente 00:34:57
he implementado el método 00:34:58
vale, pues ya está, puedo trabajar así 00:35:00
pero hombre, tener que estar 00:35:02
creando clases 00:35:04
todo el rato para cada conjunto 00:35:06
de operaciones que queramos hacer 00:35:08
cada vez que queramos crear 00:35:10
uno de estos es un poco pesado 00:35:12
entonces hay un atajo 00:35:14
un atajo 00:35:16
para darle 00:35:17
contenido 00:35:19
a las interfaces funcionales 00:35:22
que es el de las lambdas 00:35:24
entonces, ¿esto en qué se traduciría? 00:35:25
por ejemplo 00:35:28
este código en lugar de hacerlo así 00:35:31
voy a intentar ahorrarme 00:35:36
el tener que hacer el new sumar 00:35:38
voy a intentar ahorrarme 00:35:40
vale, pues venga 00:35:41
operar suma 00:35:43
y ahora 00:35:46
¿cómo lo instancio? 00:35:48
pues me puedo hacer una cosa que se llama función lambda 00:35:49
que es meter ahí 00:35:52
directamente el código que pensaba 00:35:54
meter en el método de sumar 00:35:56
el que pensaba meter en el método de sumar 00:35:58
aquí lo dejo, tan apañado 00:36:00
vale, ahí lo dejo 00:36:03
ahí lo voy a meter 00:36:04
ahí tan apañado 00:36:06
vale, pero como lo meto 00:36:09
alguna sintaxis tendré que seguir 00:36:11
vale, o sea la idea 00:36:12
repito de las landas es 00:36:14
directamente poner aquí 00:36:16
el código del método 00:36:18
que yo he metido dentro de sumar 00:36:20
y así me ahorro crear sumar 00:36:23
lo entendéis, no? 00:36:24
vale, pues como lo método 00:36:26
la sintaxis 00:36:28
de las famosas funciones lambda 00:36:33
que es una forma compacta 00:36:35
de expresar métodos 00:36:37
¿y cómo se expresan? 00:36:39
pues tiene dos partes 00:36:41
separadas por este simbolito 00:36:42
en la primera parte que se pone 00:36:45
los parámetros de entrada 00:36:49
del método 00:36:51
que yo estoy declarando 00:36:52
con la función lambda 00:36:55
pues en este caso el método que yo quiero declarar 00:36:56
tiene dos parámetros de entrada 00:36:58
op1 y op2 00:37:00
pues me pongo aquí x y 00:37:01
los métodos separados por coma 00:37:04
con el nombre que sea, ni tipo de dato ni nada 00:37:07
recordad que lambda 00:37:08
es para simplificar 00:37:10
es hacer un atajo para declarar métodos 00:37:12
directamente 00:37:14
que sean datos de interfaces 00:37:16
funcionales 00:37:18
y ahora esta función lambda 00:37:19
¿qué tiene que hacer? 00:37:21
en este caso tiene que devolverme 00:37:23
la suma de operando1 00:37:26
operando 2, ¿vale? 00:37:28
pues entonces 00:37:30
retun op1 00:37:31
más op2 00:37:35
uy, perdón, x sí, perdón 00:37:37
x más 00:37:38
sí, vale 00:37:41
y cuando son 00:37:42
dos, se ponía entre 00:37:46
paréntesis, ¿verdad 00:37:48
que sí? 00:37:51
sí, y ahora 00:37:52
si tiene un retun 00:37:54
así 00:37:56
x más 00:37:58
a ver, es que la sintaxis de 00:38:01
funciones 00:38:02
vale, a ver que me falta aquí 00:38:04
insert, ah vale, que he puesto un return 00:38:10
me faltaría esto 00:38:12
vale, pues a ver 00:38:13
ya me he hecho 00:38:19
una función lambda 00:38:23
vale, para 00:38:24
entonces repito, una función lambda 00:38:26
es una forma 00:38:33
rápida de expresar 00:38:35
el cuerpo de un método 00:38:37
vale, pues entonces son dos partes 00:38:39
separadas por este simbolito 00:38:41
en la primera parte 00:38:43
tiene los parámetros de entrada al método 00:38:45
sin tipo de 00:38:47
dato y sin nada, ¿por qué? porque eso 00:38:50
se va a inferir 00:38:51
de esta interfaz 00:38:52
si yo a esta función lambda se la estoy asignando 00:38:55
operar suma, es que ya se 00:38:57
infiere, porque operar 00:38:59
tiene int e int 00:39:01
entonces ya se infiere, no los tengo que poner ahí 00:39:03
vale, pues entonces 00:39:05
si no 00:39:11
si solo fuera uno, no hace falta 00:39:12
poner paréntesis, pero bueno, todo eso son detalles 00:39:15
de sintaxis 00:39:17
de función lambda 00:39:19
que se pueden consultar rápidamente 00:39:20
vale, en la segunda parte 00:39:22
si son seis, pues seis 00:39:24
y para abajo el coma 00:39:27
¿cómo se llamaría? 00:39:27
a ver si es más de uno 00:39:31
entre paréntesis 00:39:33
x y z 00:39:33
pepito pérez, comadita de la gana 00:39:37
como tú quieras, lo único que no pones 00:39:39
es el tipo de dato, porque es que ya se infiere 00:39:41
de aquí, de esta interfaz 00:39:43
y en la segunda parte 00:39:44
pones el código del método 00:39:47
y ya está, en este caso 00:39:49
tiene que haber un return 00:39:51
porque operar 00:39:52
tiene aquí swing 00:39:55
¿vale? entonces luego 00:39:57
aquí ya hay diferentes 00:39:59
como la idea de esto es simplificar 00:40:00
ya hay diferentes cosas 00:40:03
si solo hay una sentencia 00:40:05
no hay que poner llaves 00:40:06
si esa sentencia 00:40:08
única tiene un retun 00:40:11
el retun no hace falta 00:40:13
yo aquí lo he puesto así para que 00:40:14
se vea más claro 00:40:17
entre llaves el código con las sentencias 00:40:18
¿vale? pero esta en particular 00:40:21
esta función lambda en particular 00:40:23
se puede simplificar 00:40:25
todavía más porque solo tiene una sentencia 00:40:27
que además es la de retun 00:40:29
entonces se pueden quitar las llaves y el retun incluso 00:40:31
¿verdad que sí? 00:40:33
también 00:40:38
sí, ¿vale? 00:40:38
O sea, si sólo tiene una sentencia, se puede quitar las llaves, si sólo tiene una. Si tiene más de una, llaves y separado por punto y coma, ¿vale? Y si esto te da un valor, ese valor no hace falta que le pongas el return, ya se sobreentiende que es el valor que devuelve el método opera de aquí. 00:40:43
bueno, pues ya está 00:41:05
con esto estoy diciendo 00:41:09
oye, tú a operar 00:41:11
quiero un objeto de esta instancia 00:41:13
operar 00:41:17
cuya implementación del método 00:41:18
sea este 00:41:21
y ya se lo paso aquí 00:41:22
y aquí podría hacer lo mismo 00:41:24
con el otro 00:41:27
operar 00:41:28
multiplica 00:41:30
pues operar multiplica 00:41:32
x y 00:41:34
x por y 00:41:36
¿Veis? Y ya me olvido 00:41:40
de esta clase sumar 00:41:45
de esta clase multiplicar, esto ya no me hace 00:41:46
ninguna falta, y lo que es más 00:41:48
es que ni siquiera 00:41:54
necesito crear 00:41:56
esta variable adicional, es que se lo pongo aquí 00:41:58
directamente, que es el uso 00:42:00
habitual, que es lo que veis vosotros en 00:42:02
chagpt cuando lo veis 00:42:04
¿Vale? Entonces es que 00:42:06
de hecho hasta ni esto me haría 00:42:08
falta, crearlo en variable aparte 00:42:10
podría 00:42:12
Directamente hacer esto 00:42:14
Si no tiene, lo dejas en vacío 00:42:18
Sin parámetros 00:42:26
Esto habría sido 00:42:26
Esto es lo natural 00:42:36
Esto es lo que normalmente nos encontraríamos 00:42:37
¿Veis? O sea, lo he reducido todo mi main 00:42:42
A estas dos líneas 00:42:52
Mi calculadora solo tiene opera 00:42:54
O sea, mi aplicación de calculadora 00:42:57
Se ha reducido una barbaridad 00:43:00
si la revisamos 00:43:02
tiene una interfaz funcional 00:43:04
que marca que hay una operación con parámetros 00:43:06
que hay que hacer, pero no decimos cuál 00:43:09
y ahora tengo una calculadora 00:43:10
que me dice, oye tú dame la operación 00:43:13
que quieras, que ya operaré yo 00:43:15
pero ya está, ahí no hay ninguna 00:43:17
complejidad, es dame la operación 00:43:19
y yo opero 00:43:21
no hay que escribir más código 00:43:23
no hay que escribir más nada 00:43:25
y ahora ya, cuando yo 00:43:26
llame al método de la calculadora 00:43:29
le paso aquí 00:43:30
la operación, que es la instancia 00:43:32
de operar 00:43:35
se la paso aquí como función lambda 00:43:36
y todo esto es una abreviatura 00:43:39
un atajo de todo lo anterior 00:43:44
que hemos hecho 00:43:46
lo que realmente hay debajo es 00:43:47
mi interfaz funcional, una interfaz con un único 00:43:49
método, punto pelota 00:43:52
vale 00:43:54
ahora 00:43:55
puedo crear objetos 00:43:57
de esta clase, esos objetos 00:43:59
lo que van a tener va a ser lista de código 00:44:02
muy bien, pues entonces me declaro 00:44:04
mi clase y aquí meto esa lista 00:44:06
de código 00:44:08
y ahora ya en mi main yo instanciaría objetos 00:44:09
de esa clase y ya se los puedo pasar a mi 00:44:12
calculadora 00:44:14
pero todo eso lo podemos atajar con las funciones 00:44:15
lambda 00:44:19
que directamente 00:44:19
una función lambda 00:44:22
se sustituye directamente 00:44:24
con un objeto 00:44:26
de la interfaz funcional correspondiente 00:44:27
bueno, más o menos entendido 00:44:30
Entonces, vosotros 00:44:50
Cuando hacéis, por ejemplo 00:44:57
La típica 00:44:59
Para recorrer 00:45:08
A ver, por ejemplo, vamos a ver que tenemos aquí 00:45:09
Una lista 00:45:12
Numeritos 00:45:16
Vale, tengo aquí mi lista 00:45:17
De numeritos 00:45:31
Vamos a meterle 00:45:33
Números al azar 00:45:35
Y ahora hacemos el 00:45:36
Casting 00:45:59
Venga, vale, pues cuando vosotros 00:46:01
Mostráis esta lista, hasta ahora 00:46:06
Queremos mostrar la lista 00:46:07
Bueno, a ver 00:46:09
Lo típico sería hacer un recorrido 00:46:10
¿No? 00:46:14
Es que como lo he declarado como objeto 00:46:18
Es por referencia 00:46:20
Entonces yo creo que sí 00:46:22
No está como int 00:46:24
No sé si me explico, está como int 00:46:25
Entonces es la dirección del número, no el propio número 00:46:28
Ah, perdón, perdón, vale 00:46:31
Que se lo tengo que añadir, sí, sí, perdón, perdón 00:46:37
Eh, que sí 00:46:39
Que 00:46:41
A ver, que se me ha ido la 00:46:41
Vale, estaba ya pensando en el recorrido y mezclar las cosas 00:46:45
Pues venga, entonces 00:46:47
Para cada 00:46:49
Igual a cero 00:46:50
Mientras 00:46:54
Y sea menor que veinte 00:46:55
Ah, sí, sí, ¿verdad? 00:46:58
ahora números.add 00:47:02
esto, vale, ahora sí 00:47:06
vale, pues ahora ya sí, ¿cómo la recorremos 00:47:09
normalmente? 00:47:12
pues normalmente 00:47:15
hacemos esto, por cada 00:47:16
vale, pues que recorremos 00:47:18
la lista, pues hacemos esto 00:47:40
que queremos quedarnos con un elemento de la lista 00:47:41
que cumpla no sé qué, no sé cuántos 00:47:44
que queremos multiplicar por dos 00:47:46
todos los de la lista, pues la recorremos 00:47:48
entonces cada vez que trabajamos con listas 00:47:50
estamos haciendo for 00:47:52
todo el rato, estamos haciendo for 00:47:53
todo el rato para recorrerla, pues vale 00:47:56
no pasa nada, no es grave hacer un for para recorrer una lista 00:47:57
pero ahora 00:48:00
con esto de la programación funcional pues nos podemos 00:48:01
ahorrar líneas 00:48:03
porque yo ahora cojo mi lista, números 00:48:05
números si yo despliego 00:48:07
tiene un montón de métodos 00:48:11
y entre ellos 00:48:13
por ejemplo 00:48:17
pues tiene 00:48:18
este 00:48:20
tiene el forEach 00:48:23
entonces el forEach 00:48:26
veo que le hace falta 00:48:28
un tipo muy raro 00:48:30
un consumer no sé qué 00:48:31
¿qué será el consumer? 00:48:33
pues el consumer 00:48:37
resulta que es una interfaz funcional 00:48:38
que ya está hecha 00:48:40
con un único método 00:48:41
que recibe un parámetro 00:48:43
y hace algo con él 00:48:46
pero no devuelve nada 00:48:48
eso es un consumer 00:48:49
una interfaz funcional que ya está hecha 00:48:50
justo, pues el forEach 00:48:52
necesita que tú le digas 00:48:55
oye, dime qué hacer con cada numerito de la colección 00:48:58
y yo lo hago 00:49:02
vale, entonces el forEach 00:49:03
este método de aquí, forEach 00:49:06
es un método que lo que hay que pasarle precisamente 00:49:08
es un comportamiento 00:49:13
y es, qué hay que hacer con cada numerito de la colección 00:49:15
luego el forEach es un ejemplo 00:49:20
de método que 00:49:23
lo que hay que pasarle es 00:49:24
un método 00:49:27
o una instancia de una interfaz funcional 00:49:28
como lo queráis llamar, eso es lo que hay que 00:49:31
pasarle, lo que tú quieres 00:49:33
que se haga con cada elemento 00:49:35
entonces 00:49:36
en particular, diríamos 00:49:37
ya, pero ¿qué tipo de método? ¿cuántos parámetros 00:49:41
recibe? ¿cuántos no? 00:49:43
ya te lo está diciendo 00:49:44
la ayuda de forEach 00:49:46
te está diciendo, oye 00:49:48
yo la única interfaz funcional que me vale 00:49:50
es una de tipo consumer 00:49:53
y la interfaz funcional 00:49:55
de tipo consumer, si uno entrara 00:49:57
a jipearla, vería que es una interfaz 00:49:59
funcional con único método vacío 00:50:01
que recibe un número 00:50:03
y hace cosas, pero no devuelve 00:50:05
nada, pero no devuelve nada 00:50:07
pues eso es lo que necesita un for each 00:50:09
que le pases una lambda 00:50:11
que recibe un único valor 00:50:13
y hace cosas con él 00:50:15
pero no devuelve nada 00:50:17
porque es así 00:50:18
es un consumer válido 00:50:21
entonces 00:50:23
pues por ejemplo, ¿qué quiero hacer yo con cada 00:50:25
elemento? 00:50:27
pues por ejemplo, con cada elemento 00:50:29
quiero 00:50:31
hacer esto 00:50:32
soy x 00:50:35
vale, entonces me 00:50:46
falta aquí esto 00:50:48
y me sobra uno de estos, ¿verdad? 00:50:50
¡hala! pues ya está 00:50:52
esto es un buen uso del for each 00:50:53
porque le estoy pasando una lambda 00:50:56
que recibe 00:50:58
un único dato 00:51:00
y no devuelve nada, hace cosas 00:51:01
lo que uno le dé la gana, como si me merece aquí 00:51:04
poner 2000 operaciones y 30 00:51:06
system output del n, con que no haya un return 00:51:08
es suficiente 00:51:10
¿vale? bueno y eso es 00:51:11
así porque el for each está declarado 00:51:14
así, le tienes que pasar 00:51:16
una lambda de tipo consumer 00:51:18
o lo que es lo mismo, único 00:51:20
dato de entrada y aquí 00:51:22
lo que tú quieras, pero sin return 00:51:24
bueno, ¿y qué hace 00:51:26
el for each? pues el for each 00:51:28
para cada elemento de esta colección 00:51:30
para cada elemento 00:51:32
hace lo que tú le hayas puesto aquí 00:51:34
luego esto 00:51:36
sería idéntico al for de arriba 00:51:37
es decir 00:51:40
esto y esto hacen lo mismo 00:51:48
esto y esto hacen lo mismo 00:51:51
¿vale? 00:51:53
con esto 00:51:56
¿qué he hecho? pues me he arreglado un for 00:51:57
Lo de arriba y lo de abajo 00:51:58
Hacen exactamente lo mismo 00:52:03
Claro, yo aquí lo que no podría hacer 00:52:05
Es pasarle una lambda que no se adapte 00:52:07
Al tipo consumer este 00:52:10
Yo no puedo pasarle esta lambda, por ejemplo 00:52:11
Porque me diría 00:52:13
Perdona, es que 00:52:16
El consumer no tiene dos parámetros 00:52:17
De entrada, tiene solo uno 00:52:19
¿Vale? 00:52:21
No, bueno, aparte tendría que ponerlo así 00:52:23
¿Vale? 00:52:25
Me diría esto, me diría, eh, perdona 00:52:29
Pero 00:52:31
no es aplicable a los argumentos 00:52:33
lo siento, la lambda expression no se adapta 00:52:35
te lo estoy diciendo abajo 00:52:37
lo siento pero no 00:52:39
no me adapto, esta lambda 00:52:40
no se adapta a la firma 00:52:43
del método ACCEPT que es el método 00:52:45
que tiene el consumer 00:52:47
tiene un método ACCEPT que recibe un integer 00:52:48
un integer y devuelve un void 00:52:51
dice no, perdona, esta lambda no se adapta 00:52:52
dame una que se adapte 00:52:56
entonces, pues bueno 00:52:58
esta sí se adapta 00:52:59
¿vale? 00:53:01
x esto 00:53:03
entonces ahora si ejecutamos esto 00:53:05
pues tenemos 00:53:09
dos veces lo mismo 00:53:15
vale, la primera vez 00:53:15
en los primeros 20 00:53:19
y la segunda vez que yo no sé donde está 00:53:20
pero estará por ahí 00:53:23
esto es lo de lo que había abajo 00:53:28
de la calculadora 00:53:33
vale 00:53:34
aquí empezamos 00:53:36
59, vale, ha hecho lo mismo 00:53:40
en ambos casos 00:53:42
¿cómo sabe 00:53:43
Java que tiene que hacer 00:53:46
porque así está programado 00:53:47
el for each por dentro, el for each 00:53:50
es un método que se aplica a una 00:53:52
colección, claro, es un 00:53:54
método de list 00:53:56
y está programado para 00:53:57
que a cada elemento 00:54:00
de la lista 00:54:01
le haga la acción 00:54:03
que tú tienes aquí 00:54:06
vale 00:54:07
Pero hay otros que también pueden recibir 00:54:08
Dentro de las listas 00:54:12
Por ejemplo, números 00:54:13
Si uno cotillea por aquí, a ver cuáles reciben 00:54:15
Interfaces funcionales 00:54:17
Por su nombre 00:54:19
Porque es consumer o predicate o funcional 00:54:25
O algo así 00:54:27
No, comparator 00:54:29
Bueno, sí, comparator 00:54:32
También es una interfaz funcional, le puedes pasar como lambda 00:54:34
vale, yo estaba buscando aquí 00:54:37
aquí, el predicate 00:54:40
que se me había escapado 00:54:44
el removeFif 00:54:44
tienes que pasarle 00:54:46
un objeto de tipo predicate 00:54:49
que resulta que también 00:54:52
es una interfaz funcional 00:54:54
pero la interfaz funcional predicate 00:54:55
¿qué firma tiene en su método? 00:54:57
pues 00:55:02
recibe un valor 00:55:03
un valor 00:55:06
y te devuelve un boolean, un truco falso 00:55:06
entonces el predicate 00:55:09
sobre un elemento te dice si 00:55:11
cumple algo o si no lo cumple 00:55:13
lo que ahí te dé la gana 00:55:15
entonces, el remove if 00:55:16
yo le tengo que pasar 00:55:20
una función lambda de tipo 00:55:23
predicado, como por ejemplo esta 00:55:25
x entre 2 00:55:29
igual a 00:55:32
¿Vale? ¿Veis? 00:55:37
Esta es una función lambda de tipo predicado 00:55:42
correcta, recibe 00:55:44
un único valor y te devuelve 00:55:46
un boolean 00:55:48
te devuelve un boolean 00:55:49
entonces el remove if me la acepta 00:55:50
porque el remove if necesita 00:55:54
funciones lambda de tipo predicado 00:55:56
entonces las de tipo 00:55:58
ya esas dos nos pueden sonar 00:56:00
las de tipo consumer, funciones lambda 00:56:02
que reciben un parámetro y no devuelven 00:56:04
nada, hacen lo que sea pero no devuelven nada 00:56:06
funciones lambda de tipo predicado 00:56:08
reciben un parámetro 00:56:11
y devuelven un boolean 00:56:13
esta es de tipo predicado 00:56:14
vale, ahora la pregunta sería 00:56:16
¿qué hace el remufif? 00:56:18
pues a todos y cada uno de los elementos 00:56:20
de esta colección 00:56:22
a todos y cada uno los elimina 00:56:24
si el predicado se cumple 00:56:26
entonces lo que haríamos con un for 00:56:28
o con un iterator 00:56:32
que sería un rollo 00:56:35
es decir, eliminar los pares 00:56:36
De la colección 00:56:39
Sería un rollo 00:56:40
Sin las funciones lambda 00:56:43
Pues haríamos esto 00:56:44
¿Verdad? 00:56:47
Números.iterator 00:56:48
Y ahora 00:56:51
While iterator.next 00:56:52
No, next 00:57:01
No, has next 00:57:05
Era, ¿no? 00:57:06
Ahora sí 00:57:07
If it.next 00:57:10
Por ciento 00:57:16
por 102 00:57:19
es igual a 0 00:57:22
en iterator 00:57:24
es que no lo he parametrizado, por eso se queja 00:57:28
el compilador, es un iterator de 00:57:30
interés 00:57:32
entonces 00:57:33
id.remove 00:57:37
vale 00:57:40
id.remove, vale 00:57:40
pues este, sin lambdas y 00:57:44
programación funcional 00:57:46
este sería el código para eliminar 00:57:47
los pares, ¿verdad? 00:57:50
no lo haríamos con un for each 00:57:51
porque ya sabemos que es el concurrente exception 00:57:53
sería el código, itero por la colección 00:57:55
alguno par 00:57:58
lo elimino 00:57:59
con landas 00:58:00
es esto 00:58:03
uso el método remove if que me dice 00:58:04
oye 00:58:07
tú pásame un predicado 00:58:08
que yo 00:58:11
aplicaré a cada elemento de números 00:58:13
lo aplicaré 00:58:15
y el que me dé true lo borro 00:58:16
Pues entonces yo le paso un predicado 00:58:18
Y un predicado es una interfaz funcional 00:58:23
Que recibe un valor 00:58:25
Y devuelve un boolean 00:58:26
Entonces pues hombre, nos ahorra la vida 00:58:28
Y ya nos la ahorra mucho más 00:58:38
Si ahora ya, pero esto ya lo vamos a hacer hoy 00:58:40
Metemos esa lista en una tubería 00:58:43
Porque entonces ya 00:58:47
Los posibles métodos 00:58:48
Que podemos usar 00:58:51
Son infinitos 00:58:52
O sea, trabajar con una colección 00:58:54
Sin streams 00:58:56
a trabajar con streams, la diferencia es enorme 00:58:58
vale, entonces vamos a 00:59:00
comprobar que ambas cosas nos hacen lo mismo 00:59:02
bueno 00:59:04
no hace falta, a ver, os lo digo yo, que lo hará 00:59:06
y si no lo comprobáis y ya está 00:59:08
vale, bueno pues 00:59:09
entonces, cuando 00:59:14
copiéis y peguéis 00:59:16
landas relacionadas con colecciones 00:59:17
de Gemini 00:59:19
id entendiendo por favor que estáis 00:59:21
haciendo, que es esto, porque cada uno lo ve 00:59:23
y dice, ah esto está muy bien para cada 00:59:25
x, me dice si es par o no 00:59:27
claro, lo estás leyendo, tal cual 00:59:29
para KDX me dices para uno 00:59:31
pero claro, no hay que quedarse en eso, hay que entender 00:59:33
que esto realmente es un objeto 00:59:35
¿de quién? 00:59:37
es un objeto de este 00:59:39
del predicate 00:59:41
y predicate que es 00:59:43
una interfaz funcional, entonces si tú entiendes eso 00:59:45
cuando tú buscas método dices, ah vale 00:59:47
este necesita un consumer 00:59:49
ya sé lo que es un consumer, este necesita 00:59:51
un predicado 00:59:55
Pues ya sé lo que es, tengo que darle una landa a predicado 00:59:57
Pues bueno, ya empezamos a entender un poco 00:59:59
De qué estamos hablando 01:00:01
¿Vale? 01:00:02
Bueno, ¿bonito o no bonito? 01:00:08
¿Cómo que sí? 01:00:11
Esto es infinitamente más bonito 01:00:12
Que el JavaFXS 01:00:14
Que no tiene más que colores feos 01:00:16
Claro, tú en el consumer aquí 01:00:18
Aquí puedes poner 01:00:28
lo que quieras, por ejemplo, imagínate que yo quiero mostrar 01:00:31
solamente los pares 01:00:35
pues podría ser para cada x 01:00:37
si x por 102 01:00:41
es igual a 0 01:00:46
pues ponme aquí 01:00:49
soy x 01:00:55
y soy par 01:00:59
Claro, cualquier método 01:01:02
Soy x 01:01:08
Y soy par 01:01:10
Y si no, pues que no muestre nada 01:01:11
Entonces, aquí como solo sería 01:01:15
Una sentencia que es la if 01:01:18
A mí me dejaría no poner las llaves 01:01:20
For each if x es igual 01:01:22
No, yo creo que cuando ya pones una sentencia 01:01:26
A ver 01:01:28
Es porque me falta un paréntesis 01:01:29
No, porque 01:01:33
Este me dice este 01:01:34
y este me dice soy x y soy par 01:01:36
yo creo que es porque aquí ya 01:01:38
que he puesto un paréntesis de más 01:01:40
al final de eso tengo que cerrar el for each 01:01:42
claro 01:01:46
entonces yo creo es porque al poner ya 01:01:48
una sentencia 01:01:50
más 01:01:51
tocha, no tan sencilla como 01:01:53
una operación, ya me dice que 01:01:56
lo cierre así 01:01:58
¿verdad? porque ni con el punto ni con el 01:02:03
ya pero es que había 01:02:04
Vale, entonces ahora ya 01:02:09
Ahora ya sí, bueno, está muy fea 01:02:12
A ver cómo la 01:02:14
Vale, pues entonces este for it 01:02:15
Solo le mostraría los pares 01:02:20
Vale, del segundo recorrido 01:02:21
Solo ha hecho esto 01:02:28
Puedes meter lo que quieras 01:02:29
Vale 01:02:33
Bueno, dudas 01:02:35
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
9
Fecha:
29 de abril de 2026 - 10:15
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
1h′ 02′ 43″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
551.18 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid