20260428 InterfacesFuncionales_Lambdas - 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:
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
y
00:04:11
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
y
00:29:27
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
es
00:31:43
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
De
00:45:13
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
eh
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
38
00:53:38
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
00:55:27
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
00:59:53
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