20260202 Colecciones_2_genericos - 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:
eres una señorita
00:00:00
del siglo XVIII. Vale, pues entonces
00:00:05
con una caja que hasta ahora era un array
00:00:08
hemos accedido por posición tranquilamente y con esta nueva construida
00:00:13
por encima también por posición correctamente. Un array
00:00:17
y lo recorríamos. Pues hombre, ese también nos gustaría poder recorrerlo, ¿no?
00:00:21
Nos gustaría poder hacer algo así para ver lo que tiene.
00:00:26
mientras si sea menor que
00:00:30
ala, ya la hemos liado
00:00:32
como que con get
00:00:34
claro, imaginaos que ahora lo que quiero
00:00:37
es mostrar el resultado
00:00:40
de la caja
00:00:42
que será, o sea, lo que tiene la caja
00:00:43
get de i, verdad
00:00:46
es decir, silencio
00:00:48
vale
00:00:52
yo quiero recorrer, ver todo lo que hay
00:00:54
en todas las posiciones de mi caja
00:00:56
Igual que con un array
00:00:58
Pues ningún problema, me hago un for
00:00:59
Nombre es get de i
00:01:01
Mientras si cero
00:01:03
Y sea menor que
00:01:05
¿Qué pongo ahí?
00:01:06
¿Qué pongo ahí?
00:01:11
¿Tenéis la interrogación?
00:01:15
¿Cuál es el tamaño del array?
00:01:17
¿Pero cómo vamos a poner datos.lens
00:01:25
Si datos está oculto?
00:01:27
Yo aquí datos ni lo conozco, ni tengo acceso
00:01:28
Ni existe para mí
00:01:31
Un objeto de la clase ya está creado.
00:01:32
Entonces, ¿qué necesitamos?
00:01:39
Necesitamos un método que me diga qué tamaño tiene la raíz.
00:01:44
Necesitamos un método, no hay otra.
00:01:49
Ojalá tuviéramos, qué bien nos vendría.
00:01:50
Un método, por ejemplo este
00:01:53
Ojalá tuviera yo un método
00:01:58
Que me dijera cuál es el tamaño de esta cajita
00:02:00
Nombres en cada momento
00:02:04
Que me dijera el tamaño de esta cajita
00:02:06
Ojalá lo tuviera
00:02:08
Porque si lo tuviera, pues ya está
00:02:09
Lo puedo recorrer tranquilamente
00:02:12
Bueno, pero es que es facilísimo hacer ese método
00:02:13
Es facilísimo hacerlo
00:02:16
Porque yo hago esto y ya está
00:02:18
¿Qué pongo ahí dentro?
00:02:24
exacto
00:02:29
ala, ya está, ya tengo ese método
00:02:31
con lo cual
00:02:36
ahora ya yo puedo recorrerlo
00:02:39
si quiero, vale, y aquí está
00:02:41
el recorrido del array
00:02:49
de la cajita, array list
00:02:50
y tendría también que poder borrar
00:02:52
por posición, tendría
00:02:56
pues por ejemplo, si yo quiero borrar un elemento
00:02:58
pues ojalá tuviera
00:03:00
un método
00:03:02
dentro de ese objeto ArrayList
00:03:04
al que si yo le paso una posición
00:03:06
pues la borra, ojalá lo tuviera
00:03:08
bueno, pues ese método
00:03:12
lo tendría que hacer aquí
00:03:17
¿vale? lo dejamos aquí en blanco
00:03:19
para que lo completéis
00:03:34
vosotros
00:03:36
bueno y así le podría
00:03:36
añadir más métodos
00:03:40
si quiero pues que esta cajita
00:03:41
sea más completa, haga más cosas
00:03:43
el ArrayList real pues tiene más métodos
00:03:45
para hacer más cositas
00:03:47
como por ejemplo
00:03:48
tiene un ad
00:03:50
que
00:03:51
tú le puedes añadir de golpe un montón
00:03:53
de datos
00:03:56
en lugar de uno por uno
00:03:57
podríamos hacer aquí
00:04:00
un montón más de métodos para que esta
00:04:02
cajita sea más flexible
00:04:04
y lo que importa es que ahora yo ya
00:04:05
uso esta caja
00:04:07
y la uso tranquilamente
00:04:09
o absolutamente al margen de
00:04:11
cómo funcione por dentro porque me da igual
00:04:14
la creo
00:04:16
Inicialmente está vacía, creada
00:04:18
No tiene nada
00:04:20
Dentro, ni espacio, ni nada
00:04:22
Y luego yo voy añadiendo
00:04:24
Recupero
00:04:26
Voy borrando, hago lo que quiera
00:04:27
Con esa caja
00:04:30
¿Vale? Pues esto es una colección
00:04:31
Ya está
00:04:35
No es más que esto
00:04:37
¿Vale? Lo que pasa es que hay diferentes tipos
00:04:38
Vale
00:04:41
Pues antes de meternos más
00:04:43
Ya en los tipos de colecciones
00:04:45
Que ya están hechas en Java
00:04:47
pues porque usamos una, porque usamos otra, etc
00:04:48
etc, etc
00:04:50
vamos a dar por lo menos un pequeño salto
00:04:51
y es en este mi ArrayList
00:04:54
chulo con stream, si es muy chulo
00:04:56
pero
00:04:58
solo puedo guardar stream
00:04:59
como me gustaría a mi tener una
00:05:02
caja donde en el momento de crearla
00:05:04
yo le pudiera decir, créate
00:05:06
pero para stream
00:05:08
ahora créate pero para
00:05:09
int, ahora créate
00:05:12
pero para dabble, ojalá
00:05:14
tuviera una caja que en el momento de crearla
00:05:16
pudiera decidir
00:05:18
de qué tipo de datos
00:05:20
quiero que tenga, porque si no
00:05:22
tengo esa posibilidad, tendría que hacerme
00:05:24
mi array list chulo con string
00:05:26
mi array list chulo con int
00:05:28
mi array list chulo con dabble
00:05:30
tendría que tener ahí un mi array list chulo
00:05:32
para todos los tipos de datos
00:05:34
y si tengo alumnos, mi array list chulo
00:05:35
con alumno, o sea, me hago un mi array list chulo
00:05:38
para cualquier tipo de dato que yo
00:05:40
quiera poner aquí
00:05:42
pues hombre, no es muy operativo tener 200.000
00:05:43
clases distintas, cada una de ellas
00:05:46
para un tipo de
00:05:49
dato distinto aquí, porque mi aplicación
00:05:50
puede tener 200.000 tipos de datos
00:05:52
distintos, alumno, factura, cliente
00:05:54
no tiene sentido
00:05:56
bueno, pues menos mal que en Java tenemos la
00:05:58
posibilidad de hacer una cosa
00:06:02
que se llaman tipos genéricos
00:06:04
¿vale? menos mal
00:06:07
que tenemos esa
00:06:10
posibilidad
00:06:15
de en Java
00:06:15
usar
00:06:18
algo que se llaman
00:06:20
tipos genéricos
00:06:22
que viene a ser lo siguiente
00:06:27
te estás durmiendo
00:06:29
pero no puede ser, eso es muy divertido
00:06:32
yo no te estaba durmiendo
00:06:34
vale, entonces
00:06:39
tipos genéricos, menos mal que en Java
00:06:41
tenemos la opción de usar tipos genéricos
00:06:44
¿qué es un tipo genérico?
00:06:46
Un tipo genérico es un tipo genérico, ¿verdad? Es decir, cuando nosotros hemos declarado una variable, siempre, siempre, siempre que hemos declarado una variable, la variable X, la variable Y, le hemos puesto un tipo delante, obligatoriamente le hemos puesto un tipo delante.
00:06:48
porque es obligatorio
00:07:08
porque Java es un lenguaje que se llama
00:07:10
tipado, con lo cual cualquier
00:07:12
variable, en el momento
00:07:14
de crearla, hay que
00:07:17
decir a qué tipo pertenece
00:07:18
¿vale? bueno, esto tiene un
00:07:20
minimísimo matiz
00:07:23
cuando estudiáis cosas por ahí
00:07:24
pero bueno, que es lo de menos
00:07:26
que uno podría poner aquí var
00:07:28
y cuando pone aquí var
00:07:30
dice, todavía, todavía no me
00:07:33
comprometo, pero la primera vez que
00:07:35
le das valor, la primera vez que se lo
00:07:36
das, ya automáticamente se queda
00:07:39
de ese tipo y así queda de ese tipo para siempre.
00:07:40
Para siempre jamás.
00:07:43
Pero bueno, este matiz del var no nos
00:07:44
importa porque es una chorra.
00:07:46
Pero bueno,
00:07:50
como lo veréis por ahí por un rato,
00:07:50
lo que nos importa es que las variables
00:07:53
en Java son de un tipo concreto.
00:07:54
Desde la primera vez que las
00:07:57
usas y le das su valor, son
00:07:58
de un tipo concreto. Ese tipo ya no cambia nunca.
00:08:00
Eso hace que
00:08:04
la escritura de código en Java
00:08:04
sea un poco pesada
00:08:06
porque tienes que satisfacer muchas reglas.
00:08:07
Es el problema de Java,
00:08:10
que tienes que cumplir un montón de reglas.
00:08:11
Pero gracias a que cumples un montón de reglas
00:08:13
y eso hace muy complicado,
00:08:15
entre comillas, programar en Java,
00:08:17
los programas son infinitamente más robustos.
00:08:19
¿Vale?
00:08:23
Bueno, pues entonces,
00:08:24
cuando hemos declarado una variable
00:08:26
hemos dicho siempre
00:08:27
¿de qué tipo es?
00:08:28
Pues eso es justo lo último que yo quiero aquí.
00:08:30
Es lo último que yo quiero aquí.
00:08:34
Cuando yo declaro en mi array chulo, declaro el array de datos que va a contener los datos, esto no quiero comprometerme todavía, no quiero comprometerme, quiero dejar como tipo abierto, tipo abierto y cuando ya se cree el objeto ya diré qué tipo es.
00:08:36
Pero ahora mismo que estoy todavía declarando
00:08:56
El funcionamiento, no estoy creando nada
00:08:58
No estoy instanciando nada
00:09:00
Ahora mismo lo quiero dejar como tipo abierto
00:09:02
Bueno, pues podemos hacerlo
00:09:04
Podemos dejarlo como tipo abierto
00:09:07
Que sería
00:09:09
Lo que yo estoy llamando como tipo genérico
00:09:10
¿Y cómo lo dejamos como tipo abierto?
00:09:13
Poniendo aquí
00:09:16
Una letra mayúscula sin más
00:09:17
Normalmente
00:09:19
Se suele poner una T, pero podría poner una V
00:09:21
Podría poner una E
00:09:23
una letra mayúscula sin más
00:09:25
normalmente
00:09:27
se usa la T por tipo
00:09:29
vale, pues entonces
00:09:31
yo pongo ahí T
00:09:37
y ahora digo, yo cuando
00:09:38
esta clase se cree, se instancie
00:09:41
ya me dirán este T cual es
00:09:44
ya me lo dirán, pero ahora mismo
00:09:48
lo dejo abierto
00:09:49
y yo trabajo aquí
00:09:50
cada vez que me quiera referir a ese tipo
00:09:53
cada vez que me quiera referir, lo dejo abierto
00:09:55
entonces aquí igual
00:09:58
aquí no pondré string, sino que pondré
00:09:59
t, aquí no pondré
00:10:02
string, sino que pondré t
00:10:03
¿vale? aquí tampoco
00:10:05
es decir, lo dejo
00:10:08
abierto, ese tipo
00:10:09
de datos, ¿vale? lo dejo
00:10:11
abierto
00:10:13
y luego ya, cuando el objeto
00:10:14
se instancie, cuando
00:10:17
el objeto se cree, ya
00:10:19
diré, oye, te voy a crear a ti, me hará
00:10:21
chulo, pero te voy a crear
00:10:23
con el tipo stream.
00:10:26
Entonces, cuando se construye
00:10:28
ese objeto, se construye
00:10:30
sustituyéndose todas
00:10:31
las referencias a T por ese
00:10:34
tipo en particular. Ahora te
00:10:36
voy a crear con el tipo alumnos.
00:10:38
Pues se crea ese objeto,
00:10:40
pero ahora sustituyendo todas
00:10:42
las referencias a T con el tipo
00:10:43
alumno.
00:10:46
Con lo cual, esta única clase
00:10:48
de aquí, esta única clase
00:10:50
me vale
00:10:52
Para cualquier tipo de dato
00:10:53
Para cualquiera
00:10:55
¿Vale? Pues vamos a hacerla
00:10:56
No, no voy a empezar a cambiar todo
00:11:01
Lo voy a hacer una clase aparte
00:11:10
A ver
00:11:11
Entonces
00:11:13
Vamos a copiar esta clase
00:11:16
¿Vale?
00:11:24
Lo llamamos mearraychulo sin más
00:11:29
Vale, pues mearraychulo sin más
00:11:32
Este es el que va a valer para todo
00:11:39
Luego este string
00:11:40
Fuera
00:11:42
Este fuera también
00:11:44
Este fuera
00:11:48
Este, esto ahora lo tendremos que cambiar
00:11:57
Porque
00:12:04
Este fuera
00:12:05
Todas las referencias a string
00:12:08
Se quedan genéricas
00:12:10
Este se queda aquí fuera
00:12:12
Hombre, t, tipo
00:12:14
Hombre, si quieres lo llamamos
00:12:19
X o V
00:12:20
Sí, una letra mayúscula
00:12:21
Vale, ¿dónde tenemos más
00:12:29
referencias a string en ningún sitio más.
00:12:30
Aquí, vale.
00:12:33
Ah, aquí, aquí, aquí.
00:12:36
Vale.
00:12:41
Entonces,
00:12:43
puede que se nos haya dejado en algún sitio,
00:12:44
ahora lo, si se nos ha escapado, lo cambiamos.
00:12:47
Muchas cosas rojas,
00:12:50
¿verdad? Mucha angustia.
00:12:51
Vale, pues entonces,
00:12:53
desde el momento
00:12:56
en que en una clase
00:12:57
hago referencia a un tipo
00:12:58
genérico, como aquí,
00:13:02
que he hecho referencia en varios sitios, pero desde el momento en que hago referencia a un tipo genérico, desde el momento en que una clase se convierte dependiente de un tipo genérico, esa clase se convierte en genérica, ¿verdad? Esta clase ahora mismo se ha convertido en clase genérica, ¿vale?
00:13:04
Pues cuando una clase se ha convertido
00:13:27
En clase genérica
00:13:30
Porque depende de un tipo
00:13:30
Que yo he dejado abierto
00:13:33
Por concretar
00:13:34
Tengo que especificarlo
00:13:36
Porque si no me están saliendo todas esas cosas rojas
00:13:38
Tan angustiosas
00:13:40
¿Y cómo especifico que esta clase es genérica?
00:13:42
Poniendo aquí
00:13:46
Los corchetillos
00:13:47
Y la letra famosa
00:13:48
¿Vale?
00:13:49
Entonces se me ha quitado casi todo el rojo
00:13:54
Casi todo
00:13:56
Pero no todo
00:13:58
que llavecitas
00:13:59
pues esto es como si fuera una función
00:14:06
es el parámetro de la función
00:14:09
esto es como si fuera
00:14:10
es decir, cuando tú tienes
00:14:13
una función que depende de
00:14:17
esto es f de x de toda la vida
00:14:18
mi función depende de x
00:14:21
porque es x cuadrado más 1
00:14:22
pues esta clase
00:14:24
depende de t
00:14:26
porque lo tiene dentro
00:14:28
es la forma de expresar de que esta clase es función de t
00:14:29
¿vale? como si fuera esta idea
00:14:33
es la misma idea, esta clase
00:14:35
se convierte dependiente de T mayúscula
00:14:37
porque depende de él
00:14:39
es la manera de expresar
00:14:40
que esta clase tiene una incógnita
00:14:44
dentro todavía, que está por definir
00:14:46
y en su declaración
00:14:48
está tirando de la incógnita
00:14:49
pero luego cuando se cree el objeto
00:14:51
ya en el momento de
00:14:54
crear lo que es cuando aparecen las cosas reales
00:14:56
ahí las incógnitas no funcionan
00:14:58
hay que decir qué tipo de datos, es como aquí
00:15:00
esta es la expresión de una función
00:15:01
pero luego ya, para evaluarla
00:15:03
tienes que dar un valor a la x
00:15:06
o el 3, o el 2, o el 7
00:15:07
vale, pues esto es la misma idea
00:15:09
es decir, esta función
00:15:11
esta clase es una clase
00:15:16
que depende de t
00:15:18
cuando se creya un objeto
00:15:19
habrá que comprometerse
00:15:22
vale, aquí
00:15:24
sí me da error
00:15:26
porque como t es un tipo genérico
00:15:28
el compilador no me deja hacer ni ut
00:15:29
ni ut, porque sería instancia
00:15:31
algo que no sabe lo que está
00:15:34
instanciando. Entonces el compilador
00:15:36
me dice, no me pongas ahí
00:15:38
un new incógnita
00:15:40
porque no
00:15:42
sé qué instanciar, no sé, vale.
00:15:44
Entonces,
00:15:47
¿cómo se soluciona esto a nivel
00:15:48
de compilación? Vale, T
00:15:50
no sabemos qué va a ser. T
00:15:52
puede ser alumno, factura, un número,
00:15:54
no sabemos qué va a ser. Solo hay
00:15:56
una cosa que sabemos sí o sí o sí
00:15:58
o sí o sí, ¿qué va a ser? ¿Qué es?
00:16:00
Heredera de object.
00:16:03
¿Sí o no?
00:16:04
Sí, ¿no?
00:16:05
Porque cualquier tipo de dato, cualquiera hereda de object.
00:16:06
Bien, herencia directa porque sea su padre o bien porque sea su bisabuelo.
00:16:10
Me da igual.
00:16:14
Con lo cual, lo que sí que nos va a dejar hacer el compilador es instanciarlo así.
00:16:16
Y luego ponerle el casting.
00:16:24
Esto sí me deja hacerlo y aquí tan tranquila.
00:16:29
Y aquí lo mismo.
00:16:33
Esto a ver si me lo ofrece directamente.
00:16:34
Y me ahorro tiempo
00:16:37
No, no me lo ofrece directamente
00:16:39
Pues aquí igual
00:16:41
New object
00:16:41
Y ahora le hago el casting
00:16:45
Al apañado
00:16:50
Eso sí me lo deja hacer
00:16:53
¿Vale?
00:16:54
Y ya no tengo más errores de compilación
00:17:00
¿Vale? Cuando hay un casting
00:17:02
El compilador siempre te suele dar
00:17:06
Te da un aviso porque los castings son peligrosos
00:17:08
Te está diciendo
00:17:11
Cuidado, ¿qué estás haciendo?
00:17:13
Estás haciendo
00:17:15
un casting no verificado
00:17:16
es decir, claro que no está
00:17:19
verificado porque yo he hecho el new
00:17:21
para que estar
00:17:23
verificado tendría que haber guardado esto
00:17:25
un objeto y luego hacer
00:17:27
si ese objeto instance of
00:17:28
de no sé qué, entonces
00:17:31
hace el casting, eso sí sería
00:17:33
verificado, vale, pero
00:17:35
me da igual aquí, si es que
00:17:37
sé que yo luego
00:17:39
voy a pasarle el tipo
00:17:41
este de aquí
00:17:46
con lo cual ese casting no va a funcionar, no hay otra.
00:17:47
¿Vale?
00:17:51
Solo que le preguntaba antes,
00:17:52
¿cómo sabíamos
00:17:53
qué parámetros de cuánto?
00:17:56
Claro, es que todavía no estamos creando
00:17:57
nada. Ahora mismo esta es la
00:18:00
clase que dependerá del tipo genérico.
00:18:02
Vale, pues ahora
00:18:04
vámonos a mi main otra vez.
00:18:06
¿Vale?
00:18:14
Vámonos a mi main,
00:18:16
que era este.
00:18:20
vale, nos vamos a mi main
00:18:21
y ahora me voy a crear
00:18:31
una caja
00:18:34
pero para cadenas
00:18:35
porque ahí no tenemos ninguna otra clase
00:18:37
vamos a hacer luego otra clase para hacerlo
00:18:40
venga, pues me voy a hacer
00:18:41
caja cadenas
00:18:43
pues me hago yo
00:18:45
mi new, mi array list chulo
00:18:47
a palo seco
00:18:50
y ahora es cuando tengo que decir
00:18:51
el tipo de dato que quiero
00:18:58
yo no puedo instanciar esto
00:18:59
y no comprometerme con este tipo, ¿vale?
00:19:02
Yo aquí he dicho que depende de un tipo de dato.
00:19:11
Pues ahora, ¿cómo se lo damos?
00:19:16
Ponemos los corchetitos y ponemos el tipo que queremos.
00:19:18
Perdón, aquí que el tipo de dato, ahí.
00:19:27
Es decir, así, ¿vale?
00:19:35
Vale, pues con esto
00:19:38
Estoy diciendo, oye tú
00:19:46
Créate, pero créate
00:19:49
De tal manera que tu T mayúscula
00:19:51
Sea string
00:19:53
Y a partir de ahí
00:19:54
A todos los efectos
00:19:56
La T mayúscula se convierte en string
00:19:57
Luego este caja cadenas
00:19:59
Solo vale para guardar string
00:20:02
Solo
00:20:04
Vale, y si queremos otro
00:20:05
Pues tenemos que hacerlo con int
00:20:07
Claro
00:20:09
Por ejemplo, imaginaos
00:20:10
¿Vale?
00:20:16
¿Puedo cambiar?
00:20:21
Imaginaos que yo quiero trabajar con alumnos
00:20:22
Me voy a crear aquí rápidamente una clase alumno
00:20:24
Cualquiera
00:20:27
Una clase alumno
00:20:28
Con
00:20:32
Nombre
00:20:35
Con nombre nota
00:20:40
Voy a hacerle rápidamente un constructor con parámetros, sí, y unos get y set, y un toString, getter y setter, y toString.
00:20:52
Vale, pues imaginaos que ahora nuestra aplicación lo que va a trabajar es en lugar de con muchos stream, pues con muchos alumnos.
00:21:26
Ahora quiero trabajar con un montón de alumnos.
00:21:33
Pues no pasa nada, me hago mi ArrayList chulo, pero me lo hago para alumnos, pues ya está, comodísimo, ¿vale?
00:21:36
Me vuelvo a mi main, ahora quiero trabajar con alumnos, pues no pasa nada, me hago una caja nueva para mis alumnos
00:21:52
y le digo, oye, que ahora quiero que seas de alumnos, ¿vale?
00:22:00
como
00:22:27
matiz
00:22:30
cosa
00:22:32
como ya hemos puesto aquí el tipo de dato
00:22:33
aquí no hace falta ponerlo ¿vale?
00:22:36
se puede poner, aquí lo he puesto
00:22:38
aquí podría
00:22:40
volver a poner alumno
00:22:42
podría volver a ponerlo, pero es redundante
00:22:43
¿vale? como ya está puesto aquí
00:22:46
entonces podéis ponerlo o no ponerlo
00:22:47
en función de como parezca que queda
00:22:50
más claro el código
00:22:52
¿vale? lo importante es que
00:22:53
esté puesto en la declaración
00:22:56
En la declaración de la variable
00:22:57
En la declaración tiene que estar puesto
00:23:00
Para decir, oye, que esta caja es de alumnos
00:23:02
Y ahora yo ya esa caja la puedo usar
00:23:03
Para meter alumnos tan tranquilamente
00:23:06
En mi caja alumnos
00:23:08
Quiero meter
00:23:11
¿Qué quiero meter?
00:23:12
Pues un nuevo alumno
00:23:15
Que me voy a crear ahora mismo
00:23:16
Mi alumno
00:23:18
Carlos, que tiene un 10
00:23:19
¡Hala! Pues ya está
00:23:22
Mi caja alumnos le he metido un alumno
00:23:23
Que acabo de crear
00:23:26
Vamos a meterle otro
00:23:27
Venga, no pasa nada, le metemos otro
00:23:31
Porque aquí, vale
00:23:34
Entonces he construido
00:23:42
Una clase comodísima para guardar
00:23:45
Cosas y además del tipo
00:23:47
Que a mí me dé la gana
00:23:48
Del que a mí me dé la gana
00:23:49
Que quiero recorrer ahora la caja
00:23:51
Alumnos para ver lo que he metido
00:23:54
Dentro, bueno pues la recorro
00:23:56
Caja alumnos
00:23:58
Punto size
00:24:02
incrementando i
00:24:05
pues vamos a mostrar
00:24:06
caja alumnos
00:24:10
punto get
00:24:12
de i
00:24:14
ala
00:24:16
tan ricamente
00:24:19
con esto estoy recorriendo la caja alumnos
00:24:21
que me acabo de crear
00:24:24
recorro y voy mostrando
00:24:26
el alumno que está en la posición
00:24:30
luego es una clase
00:24:31
que si yo ya la tengo hecha
00:24:35
pues puedo usarla para
00:24:37
guardar cualquier tipo de datos
00:24:40
y manipularlo
00:24:41
insertarlo, borrarlo
00:24:46
si tuviera el delete hecho, que no tengo hecho el delete
00:24:48
con lo cual no tengo hecho el delete, si le doy delete
00:24:50
no va a hacer nada
00:24:52
pero se podría hacer, etc
00:24:53
¿vale? ¿está entendido?
00:24:55
vamos a ejecutarlo, a ver si hemos hecho algo mal
00:25:07
vale, pues aquí están mis dos alumnos
00:25:09
en la caja que acabo de meter
00:25:17
si yo en mi caja
00:25:19
alumnos, intentara
00:25:25
meter algo que no es un alumno,
00:25:27
pues no me dejaría. Si yo
00:25:30
intentara meter una cadena, por ejemplo,
00:25:31
pues lógicamente el
00:25:36
compilador no me deja.
00:25:38
Porque dice, oye, perdona,
00:25:40
caja alumnos
00:25:42
está instanciada
00:25:43
con el tipo alumno. Lo siento.
00:25:45
No puedes meter algo
00:25:49
que no sea un alumno. No puedes.
00:25:50
¿Vale?
00:25:53
Como si en caja cadenas
00:25:55
intentara meter un alumno, me dirían, no, aquí solo
00:25:56
Puedes meter cadenas
00:25:59
¿Vale?
00:26:00
Porque el método add
00:26:02
El método add
00:26:04
Ya ha cogido el tipo de
00:26:06
Dato con el que yo lo creé, lo ha cogido
00:26:09
No puedo meter otra cosa que no sea este
00:26:10
Si yo aquí he puesto alumno
00:26:12
Pues solo puedo meter alumno
00:26:14
Aquí, ¿vale?
00:26:16
Sí
00:26:19
Claro que no te deja
00:26:19
Porque solo hay un pequeñito problema
00:26:24
¿Vale?
00:26:26
Solo podemos meter
00:26:33
del tipo con que se creó.
00:26:35
Vale, bueno, pues entonces lo que íbamos a decir ahora.
00:26:39
Vale, pues esto solo tiene un pequeñísimo,
00:26:43
minimísimo, muy minimísimo y despreciable problema.
00:26:46
Y es que los tipos genéricos
00:26:49
solo se pueden sustituir por tipos objeto.
00:26:54
No se pueden sustituir por tipos primitivos.
00:26:59
No se pueden sustituir ni por byte, short, int, long,
00:27:02
Float, Double, Boolean y Chart
00:27:05
Solo por tipos
00:27:07
Objetos
00:27:09
Con lo cual me diréis
00:27:11
Jolín, por si yo quiero una caja para números
00:27:12
¿Qué hago?
00:27:15
No pasa nada porque tenemos los envolventes
00:27:16
Los wrappers de toda la vida
00:27:19
Que ya los hemos mencionado
00:27:21
Alguna vez así
00:27:23
¿Vale? Que es un
00:27:24
Un envolvente
00:27:26
Pues cada tipo primitivo
00:27:28
Tiene
00:27:34
Un tipo objeto, una clase
00:27:37
declarada por ahí por el mundo, por
00:27:39
Jabalán, que lo envuelve.
00:27:41
Int
00:27:44
tiene el envolvente int
00:27:44
se llaman groupers, clase.
00:27:47
Double
00:27:51
tiene
00:27:51
asociada
00:27:54
una clase double, o sea, hay una
00:27:56
class integer, class double, existen
00:27:59
ahí en la
00:28:01
JRE, en la librería estándar.
00:28:02
¿Para qué sirven estas clases?
00:28:05
sirven exclusivamente
00:28:07
para guardar dentro
00:28:09
un numerito del tipo que sea.
00:28:11
Integer te guarda dentro un int.
00:28:13
Double te guarda dentro un double.
00:28:16
¿Qué es lo que cambia?
00:28:18
Que esto te lo guarda en modo objeto,
00:28:19
como referencia que apunta al numerito
00:28:21
y esto es un tipo primitivo sin más,
00:28:23
sin referencia ni nada.
00:28:25
Entonces, al ser una clase,
00:28:27
los objetos Integer o Double
00:28:28
además te ofrecen métodos
00:28:30
para hacer cosas.
00:28:32
Un tipo primitivo jamás te podría ofrecer un método,
00:28:34
Pero un tipo de estos sí, te ofrece métodos que podéis mirar para ver qué se puede hacer también.
00:28:36
Bueno, pues estos tipos primitivos, estos tipos envolventes, son los que necesitamos cuando tenemos que guardar números en colecciones.
00:28:45
Los tipos
00:28:55
Por ejemplo
00:28:59
Yo me quiero hacer ahora
00:29:01
Una cajita con notas
00:29:04
¿Vale?
00:29:08
¿Puedes subir un poquito?
00:29:12
¿Dónde?
00:29:16
¿Eh?
00:29:18
Ah, no, eh
00:29:18
En algún, o sea, donde has puesto mi
00:29:18
Arraylist chulo
00:29:21
Ah
00:29:22
No, no, no, en el main
00:29:23
Aquí
00:29:26
Sí, porque he dicho que esto
00:29:29
Se puede dejar vacío
00:29:33
O lo podéis poner, da igual, según como da lo mismo
00:29:34
Porque lo que importa es que esté aquí
00:29:38
¿Vale?
00:29:39
Vale, pues entonces, ahora quiero una caja de números
00:29:41
¿Vale? Pues para los
00:29:44
Primitivos
00:29:45
Para los primitivos
00:29:46
Hay que usar
00:29:48
El envolvente
00:29:50
Por ejemplo, quiero la lista de notas
00:29:56
caja notas
00:29:58
quiero que sea
00:30:03
de números sin más
00:30:04
pues le pongo íntegro
00:30:08
y ya está
00:30:10
vale
00:30:19
los envolventes
00:30:38
se pueden usar como si fueran primitivos
00:30:41
a la hora de asignar valores, no hace falta
00:30:43
hacer el new ni nada, es decir, por ejemplo
00:30:45
aquí en
00:30:47
caja notas
00:30:49
yo quiero meter un numerito
00:30:50
tengo que meter un íntegro
00:30:53
no hace falta que haga
00:30:55
new integer porque es un objeto
00:30:56
no, es que de hecho
00:30:59
están deprecados estos constructores
00:31:00
lo podría hacer, pero es feo
00:31:02
es como los string
00:31:04
a un string le asignamos la cadena y no hacemos
00:31:06
new string, pues aquí yo puedo hacer
00:31:08
esto y ya
00:31:10
esto que sería un int primitivo
00:31:12
ya sabéis que si pongo un número en java
00:31:14
se guarda como un int primitivo
00:31:16
pues ya automáticamente la máquina virtual
00:31:18
lo promociona al tipo objeto integer
00:31:20
luego hay un intercambio
00:31:22
automático entre integer e int
00:31:24
no hay ningún problema en eso
00:31:27
vale, es decir
00:31:29
por ejemplo aquí tenéis un double
00:31:31
vale, pues
00:31:32
este es un objeto, este es un tipo objeto
00:31:35
pero ahora de asignarle algo
00:31:37
no hace falta hacerle un new
00:31:39
double, igual que al string no hace falta
00:31:41
hacerle un new string
00:31:43
le podéis asignar directamente
00:31:44
el numerito 3.6
00:31:46
que sería un double
00:31:49
primitivo, pero él ya lo promociona al tipo objeto
00:31:51
¿Vale? O sea, es fácil trabajar con los envolventes
00:31:53
Pero trabaja igual, que si fueran primitivos
00:31:56
Trabaja igual
00:31:57
Con la única diferencia de que tienen
00:31:58
Métodos
00:32:02
La única diferencia, por ejemplo, si yo me hago
00:32:02
Aquí un double de 2
00:32:06
Igual
00:32:08
A 3.6
00:32:09
El dato que tienen
00:32:12
Es el mismo
00:32:14
Pero de 1
00:32:15
Puede llamar a métodos
00:32:18
¿Veis? Double value equals float
00:32:19
pasármelo a float, compararlo con otro
00:32:21
bla bla bla
00:32:24
no es un número
00:32:25
pero sin embargo
00:32:26
D2 no puede llamar a métodos porque es un tipo
00:32:29
primitivo, es la única diferencia
00:32:31
entre uno y otro
00:32:33
pero uno se puede asignar a otro sin problema
00:32:34
a D1 le puedo asignar
00:32:37
D2 y no pasa nada
00:32:39
se asigna a uno el valor del otro
00:32:41
y a D2
00:32:43
le puedo asignar D1
00:32:46
y no pasa nada, el valor de uno pasa al otro
00:32:47
aunque uno esté en primitivo y otro esté en objeto
00:32:49
a la hora de asignarse valores
00:32:51
son indistintos
00:32:54
lo único es que uno puede llamar a métodos
00:32:56
y otro no
00:32:58
¿y por qué son interesantes?
00:32:58
pues porque para los tipos genéricos
00:33:01
para esto que nos hemos
00:33:04
encontrado ahora
00:33:06
un tipo genérico solamente puede ser sustituido
00:33:06
por un tipo objeto
00:33:10
luego yo aquí jamás podría poner
00:33:11
int
00:33:14
¿vale?
00:33:14
porque un tipo primitivo no puede
00:33:16
sustituir a un tipo
00:33:19
genérico, no puede
00:33:21
pero es tan fácil como poner
00:33:22
el envolvente
00:33:25
y como funciona igual que el innormal
00:33:27
pues ya está
00:33:29
vale
00:33:31
y ya por último
00:33:32
y nos vamos
00:33:42
y lo que es todavía más
00:33:43
emocionante
00:33:46
de hecho, podría yo
00:33:47
hacer una clase genérica
00:33:50
Y en este caso
00:33:51
Un array chulo, genérico
00:33:55
Y no decir el tipo de dato
00:33:57
Es decir, no sé si habéis
00:33:59
Intentado hacer esto
00:34:01
Ya, ya, ahora
00:34:04
Me arrepiento, pero en su momento
00:34:25
Es lo que tiene, no prever las cosas
00:34:27
Pero bueno, a ver, que vosotros tenéis
00:34:30
Vuestra propia personalidad
00:34:33
Y no tenéis que copiar todo lo mío tal cual
00:34:34
Lo hacéis, eh
00:34:36
O mucho mejor
00:34:38
Vale
00:34:40
bueno, pues entonces
00:34:42
si habéis cotilleado
00:34:45
habréis visto, anda
00:34:47
pero si me deja crear una caja sin decir
00:34:49
el tipo
00:34:51
eso no va en contra de lo que decimos
00:34:52
que cuando creamos
00:34:55
un objeto, ya ese objeto tiene que tener
00:34:57
el tipo comprometido para poder instanciar
00:34:59
algo, porque hay que hacer un mío en algún sitio
00:35:01
la máquina virtual tiene que saber
00:35:03
qué instancia, pues me está dejando
00:35:05
no comprometerlo, no es que me esté dejando
00:35:07
es que si yo no se lo digo
00:35:09
él coge uno. Y dice, pues
00:35:11
si tú no me lo dices, yo me invento
00:35:13
el que quiera. ¿Se inventa el que quiera?
00:35:15
No, no se inventa el que quiera.
00:35:17
Lo hace como object.
00:35:19
Porque la clase object existe
00:35:21
y yo no puedo instanciar un object.
00:35:23
¿Y qué es un object? Algo en lo que
00:35:25
cabe todo. Porque object
00:35:27
es la superclase divina mundial.
00:35:29
Entonces,
00:35:33
si yo hago una caja, esta caja
00:35:33
se convierte en una caja
00:35:35
muy loca.
00:35:37
porque yo le puedo meter a la caja
00:35:38
loca, le puedo meter
00:35:42
una cadena si me da la gana
00:35:43
y a la caja
00:35:45
loca, esta
00:35:47
le puedo meter un
00:35:49
niño alumno si me da la gana
00:35:51
muy loca
00:35:53
y eso la hace
00:35:57
muy problemática
00:36:00
o sea, en esta caja
00:36:01
cabe todo, porque todo
00:36:06
es subclase de object
00:36:09
todo
00:36:11
entonces todo encaja
00:36:12
en el tipo object
00:36:15
recordad de herencia e implementación
00:36:16
¿vale? cuando tú declaras
00:36:19
algo de una clase
00:36:21
ahí cabe cualquier cosa de esa clase
00:36:22
y de las herederas
00:36:25
con lo cual esto está declarado
00:36:26
como object, porque yo no lo he dicho
00:36:29
luego es object, con lo cual aquí cabe
00:36:30
cualquier heredero de object
00:36:32
y de object hereda todo
00:36:34
luego en esta caja cabe todo
00:36:36
¿es un problema?
00:36:38
hombre, no es que sea
00:36:39
es peligroso, porque si metes
00:36:41
todo en la caja, cuando luego hagas get
00:36:44
no sabes lo que estás sacando
00:36:45
no sabes si estás sacando un alumno, no sabes si estás sacando no sé qué
00:36:47
entonces, se convierte en un
00:36:50
rollo, o sea, si yo saco la posición
00:36:52
cero, la posición cero
00:36:53
tiene que ir a object
00:36:56
porque esto es un object
00:36:57
si yo saco la posición cero
00:36:59
caja.get de cero
00:37:01
y ahora object, como trabajo con
00:37:03
object, le tengo que hacer un casting
00:37:07
Me toca hacer un instance off
00:37:09
If all instance off
00:37:11
No sé qué hace esto
00:37:13
¿Eh?
00:37:15
¿Que por qué pongo aquí object?
00:37:22
Porque eso es lo que me devuelve el get
00:37:24
Object
00:37:26
Porque en la caja cabe de todo
00:37:26
Me arraila, es chulo
00:37:28
Yo le he dicho que esto es object
00:37:29
Luego lo que me devuelve es object
00:37:30
No estoy comprometiendo nada
00:37:32
Me ha cabido cualquier cosa
00:37:33
Entonces el código se convierte en un rollo
00:37:35
Porque con cada get
00:37:38
tendría que hacer aquí tropecientos
00:37:39
instansoft, instansoft alumno
00:37:42
pues haz no sé qué
00:37:44
instansoft stream, haz no sé cuántos
00:37:45
un rollo
00:37:49
¿vale? entonces hombre
00:37:51
no es el uso de una clase genérica
00:37:53
dejar meter cualquier
00:37:56
cosa, porque luego manejarla
00:37:58
es complicado, no sabes lo que
00:38:00
hay en cada sitio, tienes que hacer casting
00:38:02
tienes esos casting para
00:38:04
que no te peten, tienes que hacer instansoft
00:38:06
para adelante, entonces
00:38:08
hombre, podemos usar
00:38:10
los tipos genéricos
00:38:12
¿vale?
00:38:14
esto se llama
00:38:17
que no estamos parametrizando la clase
00:38:19
podemos usar
00:38:22
la clase
00:38:24
sin parametrizarla
00:38:24
parametrizarla es sin darle el parámetro
00:38:27
t, sin parametrizarla
00:38:31
pero
00:38:34
entonces cabe todo
00:38:38
y eso es
00:38:40
pues lógicamente peligroso
00:38:42
porque tengo que tener un cuidado
00:38:44
cada vez que saco algo
00:38:45
de ver lo que es
00:38:49
¿vale?
00:38:50
entonces, usar una clase genérica
00:38:53
sin comprometer el tipo
00:38:56
podemos
00:38:57
¿vale? asume que es object
00:38:58
asume que es object
00:39:04
se pone así porque
00:39:06
todo es un uso específico del eclipse
00:39:10
para subir por código
00:39:12
¿vale?
00:39:14
Entonces, sí, la podemos usar así, pero luego el código que viene después, cuidadín, porque de aquí solo unido que salen son objects, salen objects, salen objects, ¿y qué hago yo con los objects? Un object no tiene métodos de nada. Pues tendré que hacer casting, cuidado con los casting, porque no sé qué tipo de objeto es. Luego, hombre, si tengo un cuidado extremo en mi código, vale, pero si no, ¿qué necesidad? Lo normal es que uno use las cajas para un tipo de datos concreto y sus subclases, por supuesto, y sus subclases.
00:39:17
De hecho, el compilador se nos ha puesto en amarillo
00:39:45
Porque nos avisa
00:39:50
Nos está diciendo
00:39:51
Uy, cuidado que es un tipo genérico, amplio
00:39:53
Deberías, deberías
00:39:56
Ponerle el parámetro, deberías
00:39:59
Porque si no, la lía
00:40:02
El aviso te lo da, ¿vale?
00:40:04
El aviso te lo da
00:40:07
Vale, y ahora ya sí que
00:40:08
- 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:
- 1
- Fecha:
- 2 de febrero de 2026 - 18:57
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 40′ 15″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 509.05 MBytes