Saltar navegación

2025-03-31-Programacion - 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 31 de marzo de 2025 por Jose Manuel M.

50 visualizaciones

Clases genéricas. Colecciones I

Descargar la transcripción

Sí, entonces bueno, en verdad, estaba comentando ya, lo repito para que quede en la grabación, que nada, que la semana pasada después de grabarla, yo si queréis os lo comparto, no lo borré y lo subí, pero no lo puse visible, pero en realidad yo creo que resulta poco útil ver hacer cosas ahí y además que habrá ratos que estaremos hablando y no estaremos haciendo nada, pues estar viendo ahí algo sin mucho movimiento en la pantalla igual no resulta útil. 00:00:00
Entonces bueno, como este tema es un poquito largo 00:00:27
Si queréis, podemos hoy volver a 00:00:30
Igual nos viene bien de repaso 00:00:32
Para los que estuvisteis también en la clase pasada 00:00:34
Y además ya lo dejamos grabado 00:00:36
Por si lo queréis volver a ver 00:00:38
Y como tenemos varios días 00:00:39
Aunque sea un poquito más rápido 00:00:41
Lo volvemos a repasar, si os parece 00:00:42
Más o menos estáis parecidos 00:00:45
Los que estabais la semana pasada y los que estáis ahora incorporados 00:00:47
Si me decís que no 00:00:49
Pues continúo desde donde estábamos 00:00:51
Yo creo que sí que puede resultar a lo mejor interesante 00:00:53
Volver a hacer un pequeño repaso 00:00:55
pues venga pues nada pues eso hacemos pues eso hacemos y además arranco eclipse y empezamos a 00:00:56
hablar de ello ya vamos ya digo vamos un poquito más rápido y llegamos hasta donde el otro día y 00:01:07
avanzamos algo más de todas formas de este tema nos queda todavía no solamente esta clase la que 00:01:15
viene por lo menos también y no sé si incluso la última antes de semana santa en la de lunes que 00:01:20
viene porque luego ya otro lunes es semana santa y no sé si incluso tenemos otro día más de este 00:01:25
tema todavía algo después así que entre bueno pero entre esta clase y la siguiente seguro que nos da 00:01:31
para verlo mira el otro día os comentaba a la hora de trabajar con la con temas de memoria en los 00:01:37
programas pues tenemos las variables al uso que pueden ser o bien primitivas o referenciadas que 00:01:50
son los objetos de los cuales hacemos los niños y luego hemos trabajado con agrupaciones de objetos 00:01:55
que típicamente son del mismo tipo con los arrays ya ya conoces un poco la dinámica de los arrays y 00:02:01
cómo podemos trabajar con ellos en particular cuando estamos con bucles para recorrer todos 00:02:08
los elementos y todo esto que nos permite automatizar un montón el código pues en 00:02:13
En este contexto de guardar en memoria variables que típicamente son del mismo tipo y manejarla luego con nuestros algoritmos, 00:02:20
como os digo, tenemos los arrays, pero la ventaja que tienen los arrays es que el nombre del array en sí se nos guarda. 00:02:30
Cuando hacemos una reserva de espacio de memoria para un array, lo que hacemos es que el nombre del array coge una posición de memoria 00:02:40
y a partir de esa posición es a partir de la cual se van 00:02:47
aguardando los elementos y luego 00:02:51
vamos a suponer que estamos hablando de una variable 00:02:53
de tipo entero, un array de tipo 00:02:56
entero, pues lo que sucede es que el siguiente elemento 00:03:00
está en esa misma zona de memoria donde está el nombre 00:03:03
del array desplazado, el segundo de los 00:03:05
enteros que está en el array, el tamaño de un array y el tercero 00:03:09
desplazado, dos por el tamaño de un entero y el cuarto 00:03:12
2, 3 por el tamaño de un entero. Esto que supone que como está 00:03:15
muy identificado el sitio donde están esas variables, los accesos son muy 00:03:18
rápidos y tienen muy buen rendimiento en términos de ejecución 00:03:23
en el manejo de los arrays. ¿Cuál es el principal 00:03:27
inconveniente que tenemos en los arrays? Vamos a llamarlo 00:03:31
aquí call, que ya tenemos uno de colecciones, 00:03:35
para ir haciéndolo desde cero. El inconveniente 00:03:38
que tienen los Arrays es que en el momento 00:03:42
en el que definimos el Array, recordad que os decía el otro día 00:03:45
que tenemos que identificar el tamaño que va a tener 00:03:48
ese Array. Si lo dimensionamos 00:03:51
muy grande, probablemente habrá elementos que no utilizamos 00:03:54
de ese Array, pero habremos 00:03:57
hecho esa reserva de espacio de memoria, es decir, esos recursos los tendremos 00:04:00
bloqueados en nuestro programa, aunque luego no vayamos 00:04:03
a utilizarlos y si intentamos 00:04:06
ajustar mucho el tamaño del número de elementos 00:04:09
De cara a no reservar mucha memoria RAM, el inconveniente que tenemos es que si no tenemos certeza del número de variables que vamos a tener al final en el array, pues se nos pueda quedar pequeño y ya no podemos redimensionarlo a algo más grande. 00:04:12
El ejemplo que os ponía era el de un estadio de fútbol de un equipo grande que tenga 40.000 espectadores, pero habrá días que jugarán los Benjamines del equipo y irán 100 personas y otros días irán 40.000. 00:04:26
Si el programa es el mismo, si reservamos para 40.000, bloqueamos muchos recursos para el día que van los infantiles, que van 100 personas, pero si hacemos un tamaño de un array de 100, lógicamente cuando vayan 40.000 ya no nos va a valer ese array. 00:04:40
A los Array lo llamamos estructuras estáticas de datos y con lo que vamos a trabajar en este tema, que son las colecciones y los mapas, son estructuras dinámicas. 00:04:57
¿Qué pasa con las estructuras dinámicas? Las estructuras dinámicas cuando las definimos no tenemos que identificar el número de elementos que van a guardarse en esa colección o en ese mapa, con lo cual no hacemos una reserva previa y según vayamos incorporando elementos, instancias de objetos referenciados o de variables a las colecciones o los mapas, en ese momento para cada una de ellas se hace su propia reserva. 00:05:20
si utilizamos una colección, el día que van 00:05:52
100 personas al campo con el ejemplo anterior, pues añadiremos 00:05:57
100 elementos a la colección y se hará la reserva para esas 100 personas 00:06:01
no para 40.000 como nos veíamos obligados a hacer con el array, pero el día que 00:06:05
vayan 40.000, pues al añadir 40.000 veces elementos a la colección 00:06:09
pues la reserva será de 40.000, en este aspecto 00:06:13
es mucho más flexible las colecciones, que es lo que sucede con las colecciones 00:06:17
Aparte de esa característica que las convierte en estructuras dinámicas, las colecciones trabajan con ciertos algoritmos por detrás cuando están programadas que permiten que puedan admitir o no admitir duplicados al almacenar esa información, cosa que no tenemos control a no ser que la hagamos de forma externa con los arrays. 00:06:22
Si nosotros en nuestro programa gestionamos, hacemos las comprobaciones para que no haya duplicados en un array, claro que no los tendrá, pero en sí un array no tiene un software asociado para evitar esto. 00:06:43
Las colecciones, ciertas colecciones, tienen esa característica de que no van a admitir duplicados. 00:06:56
Los elementos de un array pueden estar ordenados, pero será en función de si le aplicamos algoritmos. 00:07:02
Si un día tenemos tiempo, hacemos algún algoritmo de los más sencillos, por ejemplo el de la burbuja o algunos por ahí que típicamente se trabajan sobre datos para ver cómo se ordenan, pero en principio los arrays no están pensados para tener un código que esté asociado con que estén ordenados. 00:07:07
En cambio, las colecciones, algunas sí que están ordenadas. Es decir, hay diferentes colecciones, que después las identificamos unas y otras en el gráfico de colecciones que tenemos, que unas están ordenadas, otras no están ordenadas, unas permiten duplicados y otras no permiten duplicados. 00:07:28
¿Qué sucede? Que claro, el hecho de que los datos de las colecciones y los mapas 00:07:49
nos permitan gestionar todas estas cosas, que haya diferentes tipos 00:07:54
y que no sean contiguos en tanto en cuanto al almacenamiento en memoria RAM 00:07:57
cuando las vamos guardando, pues supone la ventaja de no tener que reservar 00:08:03
toda esa memoria RAM y tener esos servicios, pero la desventaja de que 00:08:08
todo eso lleva cierto tiempo. Al final estará corriendo en esas librerías 00:08:13
que implementa la colección, un código que cada vez que añadamos un elemento 00:08:17
no será directamente como un array, aquí lo pongo en esta posición de memoria, 00:08:23
es un entero, guardo el 5 y se acabó. 00:08:27
Una colección tendrá que hacer sus comprobaciones de si ya está en la colección, 00:08:29
si es un caso de duplicados, si es ordenado tendrá que posicionarlo 00:08:33
en un determinado sitio en lugar de otro. 00:08:37
Un poco esas son las diferencias entre unos y otros. 00:08:41
Las colecciones y los mapas se apoyan en ciertas tecnologías que tenemos en Java ya disponibles, que son las interfaces, por ejemplo, que ya conocemos. 00:08:44
acordaros que en cualquier clase hemos visto en temas anteriores que pueden implementar una interfaz 00:09:02
que viene a ser que la interfaz define una serie de métodos pero no los desarrolla 00:09:07
entonces si implementas interfaz es como si firmases un contrato diciendo yo que ahora mismo estoy poniendo en el código 00:09:14
que voy a implementar esta interfaz me obligo a desarrollar estos métodos 00:09:21
Y otras cosas que tienen son las clases genéricas, que es sobre lo que estuvimos echando un buen rato el otro día y que paso a contaros ahora. 00:09:25
Entonces vamos a ver un poco el concepto de clases genéricas, básicamente porque luego es algo que utilizan los mapas y las colecciones. 00:09:36
entonces una una cuando cada vez que nosotros definimos una clase las clases y los métodos 00:09:44
genéricos cada vez que nosotros definimos una clase pues aquí tenemos una serie de atributos 00:09:53
será de tipo int y valor por ejemplo en este caso string ese info y qué sucede si en otra 00:09:59
Ahora necesitamos, imaginaos que esta clase que la hemos llamado call, que vamos a suponer que tiene estos dos atributos, aguarda en un momento dado información que tiene que ver con valores enteros de un determinado rango, el que aceptan los enteros. 00:10:11
Podríamos definirlo así. Pero si luego resulta que tenemos una clase que es prácticamente igual que esta, pero, bueno, pues es en otro contexto. Imaginaos que es la distancia, esto es distancias en kilómetros y estamos, pues un entero, claro, admite números muy grandes. 00:10:27
Imaginaos que está este ejercicio, esta clase hecha ahora en el contexto de distancias entre ciudades en un continente. Pues bueno, pues con las distancias que permite un entero en kilómetros perfectamente nos vale una variable que sea de este tipo, entera. 00:10:47
Pero imaginaos que ahora cogemos y decimos, oye, aparte de la distancia en kilómetros, estamos pensando que igual también podríamos aplicarlo a distancia planetaria, con lo cual ya igual la distancia en kilómetros entre diferentes planetas, no sé exactamente decirlo, pero bueno, por buscar un ejemplo de algo muy lejano, un planeta que esté muy lejos, pues igual ya el número que nos permite el rango de un entero no nos da. 00:11:10
entonces en ese contexto a lo mejor sería interesante que esta variable fuera de tipo long 00:11:34
¿qué sucede? que al uso con las clases que tenemos al uso si esto lo definimos como entero es entero 00:11:39
y si esto lo definimos como long es long pero nos gustaría que en unos contextos esto fuera un entero 00:11:46
y en otros contextos esta clase fuese un long pues para esto es para lo que podemos utilizar 00:11:52
las clases genéricas para que en el momento de construir un determinado objeto de esta clase 00:11:58
sin tener necesidad de crear dos clases distintas 00:12:04
simplemente por este matiz, uno de los objetos 00:12:08
considera esta distancia como entero 00:12:10
y otro de los objetos lo considere como long 00:12:13
la sintaxis que nos permite trabajar con esto 00:12:15
es la siguiente 00:12:20
podemos poner aquí 00:12:23
entre el símbolo de mayor y menor 00:12:24
un nombrecito, una S 00:12:28
y esta S está intentando identificar un tipo 00:12:29
que pertenece al rango entero de toda la clase genérica. 00:12:33
Entonces, si yo pongo aquí ahora S, resulta que S 00:12:38
es este tipo, que no hemos dicho de momento si es 00:12:41
un long o es un entero, pero cuando instanciemos un objeto de la 00:12:45
clase call, en ese momento será cuando le daremos, identificaremos 00:12:49
este tipo. Entonces, para un objeto que lo identificamos como 00:12:54
int la S, resultará que esta S trabajará como 00:12:57
un entero y lo podremos tener en el contexto 00:13:01
de distancia entre diferentes localidades en Europa 00:13:04
y cuando instanciamos otro objeto diferente 00:13:08
si estamos pensando en distancias 00:13:11
planetarias, pues al definir ese objeto 00:13:14
lo pondremos como un long, con lo cual esta variable 00:13:17
será un long. Ambos dos valores son 00:13:19
de tipo entero, pero los diferencia 00:13:22
el rango y la cantidad de memoria RAM que 00:13:25
tienen que reservar para guardar esos datos. 00:13:28
Entonces, mira, si cogemos aquí y definimos otra clase, que sea la clase principal, por ejemplo, voy a marcarle aquí para un escribir public static void main, que directamente me lo haga él. 00:13:31
entonces tenemos a la clase principal, la clase stackall 00:13:47
si yo lo que quiero es 00:13:52
definir 00:13:54
bueno, una 00:13:59
si yo lo que quiero es definir 00:14:00
que este valor 00:14:04
trabaje como un entero, pues entonces lo que podría 00:14:08
hacer aquí es definir un objeto de la clase call 00:14:12
mi c, vamos a decir 00:14:14
y a la hora de identificar el tipo que va a ser este 00:14:17
esta variable esa se la ponemos aquí 00:14:22
y aquí vamos a poner el primero int que no nos va a dejar 00:14:26
fijaros, tendríamos que hacer un new int aquí 00:14:30
un new call y se me queja 00:14:36
¿por qué motivo se me queja? pues se queja porque los tipos primitivos 00:14:44
tal cual no se pueden meter como tipos en las clases genéricas 00:14:48
entonces si lo que me interesa es un int tendré que utilizar su clase 00:14:52
grupper, esta que teníamos, acordaros que tenía las funciones 00:14:56
asociadas con cada uno de los tipos primitivos. Para el tipo primitivo 00:15:01
int, teníamos la clase grupper integer. Y esta 00:15:05
tiene una serie de métodos que aplican a los datos int, porque en sí 00:15:09
las variables primitivas no tienen 00:15:12
métodos con los que trabajar. Acordaros, por ejemplo, el método parseInt que tenemos en la clase 00:15:16
grupper integer. Entonces aquí le diríamos integer. 00:15:21
ahora ya me compila veis de lo que le estoy diciendo aquí es que este objeto en particular 00:15:24
tendrá un parámetro que será que será genérico y este parámetro genérico queremos que sea 00:15:33
considerado como un íntegro entonces lo que pongo íntegro cuando estoy dando de alta este objeto es 00:15:44
es lo que se asocia a esta S, entonces todo lo que aparezca en el ámbito de la clase call como S lo estará considerando justo para este objeto en particular como un íntegro, entonces en este caso esto sería un íntegro, si yo cojo y aquí defino otro objeto, el long no sé cómo es la clase grupper del long, vamos a poner double, mi C2 otro objeto diferente y hago un new call 00:15:50
Pues en este caso, double, que no es long como decía, es que long es igual que el tipo, la clase grupper, porque mirad aquí me compila, pero con la L mayúscula. 00:16:33
Bueno, pues si consideramos que para otra ejecución el objeto miC2, cuando trabajemos con este objeto de la clase call, va a ser para distancias entre planetas, pues me interesaba que la S tuviera un rango más grande. 00:16:49
Entonces utilizo el wrapper del tipo long, entonces esto es a lo que se asocia esta S y todo lo que aparezca en el rango, en el ámbito de la clase, por lo tanto para el objeto donde haya una S, para ese otro será un long. 00:17:04
En un caso es un entero y en otro caso es un long. 00:17:19
Esto es lo que nos permite este tipo de clases, son muy útiles en tanto en cuanto no tengo que redefinir código para diferentes clases simplemente por algún tipo de alguno de sus atributos o alguna de sus variables que tenga por aquí. 00:17:25
Y esta definición de tipos abstractos se puede hacer tanto a nivel de clase entera, como es el caso, como a nivel de método. Entonces, para definir un método que tenga información también de esta genérica, vamos a definir un método. 00:17:40
aquí decíamos public class, aquí para el método, volvemos a definirlo 00:18:00
como entre corchetes, ponemos ahí 00:18:06
un par de variables, y el otro día tengo aquí una chuletilla 00:18:10
de lo que hicimos el otro día, definimos un método tamaño 00:18:15
que recibía aquí 00:18:18
unos parámetros, por aquí 00:18:21
public, vamos a decirle que no devuelva nada, public void 00:18:27
el tema genérico 00:18:31
lo estamos identificando por aquí 00:18:34
como ya me compila 00:18:36
y este tamaño decíamos por ejemplo que recibiese 00:18:37
del tipo T 00:18:40
que este tipo para este método 00:18:42
será una vez una cosa, otra vez otra 00:18:44
cuando estemos llamando al método 00:18:46
pues definíamos un array 00:18:48
del tipo J 00:18:50
definíamos otro array 00:18:55
del tipo T 00:18:56
definíamos una variable, volvemos a utilizar 00:19:01
el tipo T, igual que aquí 00:19:04
que será el que está asociado y luego identificado al llamar al método con esta variable. 00:19:05
Y aquí poníamos, para ver que como ese está definido en todo el ámbito de la clase, 00:19:16
pues también lo podemos utilizar no solo como atributo aquí, sino que lo podemos utilizar dentro de nuestro código. 00:19:24
Aquí, por ejemplo, podríamos poner ese dato. 00:19:30
y aquí podríamos definir una variable local en este método que fuera SA 00:19:32
pues ya está, esta S será del tipo en cada una de las 00:19:37
instanciaciones de objetos según se haya pasado por aquí 00:19:41
según estábamos haciendo aquí pues una vez sería integer y otra long 00:19:45
entonces al llamar este método, fijaros que recibe este método 00:19:49
una raíz de T, una raíz de J 00:19:59
una variable T y una variable de lo que sea esto 00:20:03
si yo pongo mid punto el método tamaño por aquí lo tenemos este va a recibir una raíz de t como 00:20:08
como identificamos que va a ser t y j cuando llamemos al método de igual forma que aquí 00:20:26
lo habíamos definido al instanciar el objeto aquí pues aquí lo definimos creo que es aquí 00:20:34
donde hay que ponerlo a que van a corresponder esos esas variables entonces por ejemplo ponemos 00:20:42
que sean integer, string e integer, es decir, el primero 00:20:52
de los dos tipos que estamos pasándole de forma genérica 00:20:57
en este caso al método tamaño, que se considere un string 00:21:01
y el segundo un integer, es decir, el primero donde aparezca 00:21:04
t, pues estará considerado como string y el segundo donde aparezca j 00:21:09
estará considerado como entero. Además, esta s 00:21:12
en particular, como es para el objeto 00:21:16
mid, para el objeto mid es un íntegro, entonces la s será un íntegro, la t será un string y la j será otro íntegro, esto podría ser cualquier tipo, incluso de clases propias nuestras, si tenemos aquí una clase persona, pues podríamos decir que donde aparece k la j, pues que sea persona, pues ya está, pues persona, lo que tocase, bueno, para hacer una ejecución que tenga sentido, vamos a definir estas cosas, este recordad que 00:21:19
es un string un array de t 00:21:49
una raíz de té y te hemos dicho que es un stream pues vamos a hacer una raíz de strings string 00:21:56
desear 00:22:04
igual año 00:22:06
string damos tamaño al string y decimos que sea de por ejemplo de 10 00:22:09
Este primer dato que le pasamos es una raíz de string el segundo 00:22:14
es una raíz de j 00:22:19
jota es el segundo de los 00:22:21
atributos genéricos que tenemos aquí 00:22:23
y estamos diciendo que sea íntegra pues nos hacemos una red íntegra íntegra 00:22:26
igual año 00:22:36
íntegra 00:22:40
a su manera de cinco 00:22:41
lotes y 00:22:47
se asignamos aquí 00:22:49
el tercero de ellos es una variable de tipo t 00:22:52
que recordamos que es esta 00:22:56
que es string, pues decimos string s info, vamos a poner s info, se me queja porque no está inicializado, vamos a decirle aquí hola, y el cuarto, pues bueno, pues es una variable que aquí se va a llamar de forma local dato, que es del tipo s, y ese lo tenemos identificado, también es genérico, pero a nivel de toda la clase, 00:22:58
y en particular para este objeto hemos dicho que esa S sea un integer. 00:23:31
Entonces podemos poner aquí integer igual a 5. 00:23:37
Fijaros que estamos definiendo objetos de la clase Grouper 00:23:46
porque para que sea genérica nos obliga a que sea la clase Grouper 00:23:49
no valdría meter la int. 00:23:52
Pues ahí lo tenemos. 00:23:56
pues ahí tenemos una llamada y en particular otra llamada con este con mitos pues podría 00:23:56
ser completamente diferente podríamos tener imaginaos que tenemos aquí vamos a los bailamos 00:24:03
estos el primero que sea el íntegro y el segundo que sea el estrés ya no le gusta porque porque no 00:24:10
existe con esta distribución verdad es el primero en una raíz de esto pues vamos a poner aquí este 00:24:17
array, el segundo sería este otro, esto sería, seguiría siendo mid, vale, el tercero sería un entero, vamos a poner un, no lo deja directamente, así, y el cuarto, bueno, pues sería, se mantendría siendo un entero, ¿por qué?, porque sigue siendo el objeto mid, que lo tenemos aquí, fijaros, si cogemos y hacemos esto, pero en lugar de para el objeto mid, ponemos mid2, 00:24:22
MIG2, resulta que este tiene un long aquí. Es decir, este valor no le está gustando ya. 00:24:55
Sí que es verdad que en el método estamos manteniendo los dos mismos que aquí, con lo cual le gustan, 00:25:02
pero este, que es un integer, realmente no es. Recordad que este es este tipo de datos. 00:25:07
Y MIG2, he dicho que ese sea long. Con lo cual aquí tendría que meter un long. 00:25:15
directamente si yo pongo aquí un literal resulta que lo considera un íntegra entonces dice 00:25:25
no me gusta esto vamos a poner aquí vamos a hacer un casting a long no tampoco le gusta 00:25:50
y de que se me queja a crear un casting a long pero al tipo primitivo me dice bueno pues ahí 00:25:58
lo tenemos y ya me compila veis bueno pues un poco esta es la idea de los de los casting de 00:26:14
las clases genéricas aquí poníamos el otro día vamos a completar la parte de esta del ejercicio 00:26:23
poníamos un sistema println y mostramos las diferentes longitudes la información y el 00:26:34
dato entonces para el método este tamaño entonces podemos a poner aquí ar 1 punto 00:26:41
lens muestra una longitud más ar 2 punto lens también más y la información de 00:26:51
estos dos datos veníamos separamos otra vez con otro guión 00:27:06
info volvemos a separar con un guión más 00:27:11
datos y bueno vamos a hacer una ejecución a ver qué pinta tiene para que nos saca la información 00:27:19
fijaros primero muestra este este este tenía una raíz de strings que tenía de tamaño 10 esto es 00:27:31
sistema este sistema println es el que muestra el método tamaño aquí que acabamos de codificar 00:27:40
pero bueno pues mostraba primero el tamaño del primero de los arrays estábamos diciendo que 00:27:47
fuera de tipo string y efectivamente el array lo hemos dimensionado 00:27:54
con tamaño 10, luego el segundo de los bloques 00:27:58
mostraba la longitud del segundo de los arrays, este segundo array era de tipo 00:28:02
j y el tipo j que estamos identificando 00:28:06
aquí es el de integer y el array justo es este que le hemos pasado 00:28:10
fijaros, que tiene tamaño 5, pues aquí tenéis el 5 00:28:13
luego pasamos 00:28:18
una variable tipo string y le decíamos que fuese ese info 00:28:22
fijaros hola, pues aquí tenemos el hola y luego un valor 00:28:26
que en particular era tipo entero y ese entero 00:28:30
era justo de este tipo, fijaros como es el que 00:28:34
identificamos aquí, es decir entero 00:28:38
fijaros como es un integer que le hemos asignado valor 5 00:28:42
y es aquí donde lo tenemos. Y aquí hemos bailado 00:28:45
estos dos datos, el 5 sigue siendo lo mismo, porque sigue siendo sobre el mismo 00:28:50
objeto que le hemos indicado que sea aquí integer, y hemos vuelto a pasarle 00:28:54
el mismo valor, y val, y aquí al bailar los datos, los dos 00:28:58
a raíz, hemos puesto integer y string, pues ya las 00:29:02
longitudes están cambiadas, 5, 10, y 00:29:05
este era una variable que teníamos 00:29:10
de tipo t, info, que para esta segunda llamada 00:29:16
bueno, pues como es de tipo T sin T, le estamos pasando un 3 aquí fijo 00:29:20
está un poco la jugada, y el otro día ya para terminar de 00:29:25
dejar un poco, dar una vuelta y dejar claro cómo funcionaba 00:29:30
esto y terminar de creernos de verdad lo de los tipos 00:29:35
que estábamos considerando, pues lo que hacíamos era 00:29:38
crear un método que habíamos llamado validar 00:29:42
public void validar o algo así 00:29:47
nombres da un poco igual en realidad, ahora lo llamábamos 00:29:50
y bueno, para tener certeza de que efectivamente 00:29:54
el tipo de S era el que 00:29:59
nosotros teníamos, el que nosotros le pasábamos a distanciar el objeto 00:30:03
se nos ocurría utilizar, bueno, pues algo con lo que hemos 00:30:07
trabajado ya en alguna tarea, que era el instanceOf 00:30:16
entonces decíamos, sí, la variable 00:30:20
y distancia, distance of, es del tipo 00:30:26
integer, pues que haga algo 00:30:32
si no es del tipo integer, pues no entrará por aquí 00:30:37
y decíamos else if, si la variable es de tipo long 00:30:40
fijaros que es esta variable que está aquí identificada con s 00:30:49
en realidad, podría ser cualquiera según el objeto que vayamos creando 00:30:55
pues que haga alguna otra cosa, vamos a poner un else por si no es ninguna de las dos 00:30:58
y entonces aquí ponemos un system.out.println 00:31:03
ese es de tipo, y si entra por este 00:31:11
entendemos que es porque va a ser un entero, la variable esa 00:31:25
más integer, no puede ser eso, tengo que ponerlo aquí 00:31:28
así, ese es de tipo integer en este caso 00:31:36
en este otro caso vamos a decir 00:31:43
que es de tipo long, y aquí decimos que es de otro tipo 00:31:49
y aquí fijaros, vamos a definir un objeto que sea 00:31:58
S de tipo integer, otro 00:32:11
objeto, en este caso mi C2 que sea de tipo 00:32:15
long y en mi C3 otro objeto diferente que sea 00:32:19
de tipo string, por ejemplo, o como luego además lo vamos a necesitar 00:32:24
vamos a crear una clase persona para dentro 00:32:30
del proyecto para poder decir que para que no sean 00:32:36
solo los tipos propios en la clase genérica 00:32:39
de lo que tenemos ya en Java, pues que sea de tipo 00:32:42
persona vale entonces para mi C3 como le estamos diciendo aquí que sea de tipo persona resultará que 00:32:45
ese será de tipo persona y ahora lo que vamos a hacer va a ser mi C punto validar 00:32:55
y C2 punto validar y mi C3 punto validar y el resto lo voy a comentar vale pues entonces 00:33:04
le damos aquí a ejecutar y me dice que todos son de otro tipo, pues muy bien, estupendo 00:33:21
a ver si vemos qué es lo que ha pasado, pues no lo sé, qué es lo que ha pasado, no lo entiendo 00:33:26
a ver, vamos a poner aquí, a ver, vamos a poner aquí this, no veo qué es lo que nos está pasando 00:34:00
a ver, vamos a crear un constructor, vamos a hacer una, a ver, object voy a poner aquí 00:34:42
a ver si inicialmente lo está considerando object todos, no, no entiendo 00:35:00
vamos a inicializarlo por si al no haber tenido 00:35:15
ningún acceso, no entiendo que es lo que está pasando 00:35:29
vamos a poner aquí ese dato, constructor típico 00:35:33
constructor copia, decimos y distancia 00:35:37
igual a dato y aquí entonces le tendríamos 00:35:40
que pasar un integer, un 2 00:35:50
un log, un 4 y aquí 00:35:52
una persona, de verdad que no me entiendo, me dice que son todos sin Tigger 00:35:57
Tigger Long, persona, pues no sé qué es lo que ha pasado aquí 00:36:24
el otro día yo juraría que no funcionó esto, le echo un ojo un minuto más 00:36:43
y no pierdo más tiempo, porque tampoco es especialmente 00:36:50
trascendente para entender las colecciones esto, pero 00:36:53
Tigger Long, ¿veis alguien lo que puede estar pasando? 00:36:56
¿veis alguna cosa rara? Bueno, para aquí 00:37:12
Y luego, cuando acabemos la clase, una vez que hayamos cerrado la grabación, por no estar aquí mareando mucho, intento echarle un ojo y si veo el por qué, os lo pongo en el aula virtual. 00:37:23
De todas formas, teníamos aquí el ejercicio de la semana pasada. No, no, no, no se te preocupes. Esto de las genéricas es porque entendéis cómo va, pero yo no creo que vayamos a hacer mucho más. 00:37:34
a ver, genérica 00:37:48
no llegamos a hacer esto el otro día 00:37:50
por lo que veo, bueno 00:38:03
luego en cualquier caso lo he hecho un ojo y si lo veo 00:38:04
no entiendo muy bien 00:38:07
el por qué no está 00:38:09
indicándonos el tipo 00:38:10
yo pensaba que no lo iba a indicar y creía también que lo habíamos 00:38:12
hecho el otro día y que había funcionado pero no lo veo 00:38:15
en el código del otro día, vale 00:38:17
aquí dejamos esto aparcado 00:38:18
yo, ya os digo, esperaba que aquí 00:38:20
me fuese a indicar cada uno de los tipos 00:38:23
ahora ya sí que no entiendo nada porque me dice 00:38:25
que todos son integer 00:38:27
cuando además, porque antes cuando decía no es de ningún tipo, digo a lo mejor es que es de 00:38:28
object y no he hecho un casting o algo, pero que me diga que persona es 00:38:32
de un integer, no lo entiendo, bueno, nada, aquí 00:38:36
dejamos las genéricas, si veo luego algo de por qué es, os lo digo 00:38:40
pasamos a las colecciones, vale, fijaros como 00:38:44
en la teoría tenemos este 00:38:48
diagrama que os comentaba, una vez ya hemos hecho la diferenciación 00:38:52
entre arrays y colecciones que diferencian unas y otras comentaros que las las colecciones tienen 00:38:56
bueno se organizan con las colecciones son colecciones y los mapas mapas pero en línea 00:39:03
general las estructuras dinámicas bien son mapas o bien son colecciones y con esa diferenciación 00:39:11
luego tenemos dos criterios principalmente para trabajar con ellos si están si no se preocupan 00:39:18
de tener orden, no están ordenados sus datos 00:39:26
y el otro criterio es si se pueden repetir, 00:39:29
si hay repetidos. Pues según el enunciado de un ejercicio 00:39:34
pues resultará que me interesará que estén con un determinado orden o que no. 00:39:40
Yo que sé, hay más que deciros. Imaginaos que es una colección 00:39:43
con el listado de clase, pues típicamente nos va a interesar que estén 00:39:47
ordenados o estamos acostumbrados por el primer apellido. Nuestro número 00:39:51
de lista, va por el primer apellido, si es igual el primer apellido, alfabéticamente 00:39:55
por el segundo. Pero por ejemplo, entonces ahí 00:39:59
igual me interesaba que fuese algo ordenado 00:40:03
utilizar una de las colecciones que están ordenadas. En otro contexto 00:40:07
yo que sé, vamos a comprar una tienda, la gente que va a comprar, pues bueno 00:40:11
me interesa tener un registro de la gente que va a comprar, pero no necesariamente con un orden 00:40:15
simplemente si fulanito viene a tal hora, pues ya está 00:40:19
pues la incorporo, pero que no esté por delante 00:40:23
en el orden de toda la colección de datos 00:40:26
de otra persona que haya venido antes porque su apellido 00:40:30
alfabéticamente sea anterior, pues nada, pues ya está 00:40:32
en ese contexto me interesa que sea sin orden, pues utilizamos 00:40:35
una que no tenga orden, y luego 00:40:39
el criterio de repetidos, pues tenemos colecciones con 00:40:41
o sin repetidos, y los que tienen repetidos 00:40:45
pues nuevamente vuelve a ser un poco en el contexto 00:40:48
funcional de la aplicación que estamos haciendo 00:40:50
es la gente que quiere acceder a un supermercado pero justo lo que me interesa este dato recogerlo 00:40:52
este dato con independencia de si es una persona ha venido tres veces este día o ha venido una 00:40:59
sola vez bueno pues si me interesa si ha venido tres veces que quede registrado en tres ocasiones 00:41:05
pues lo que haré será utilizar una colección que me permita repetidos con lo cual una persona con 00:41:10
determinado nombre y ese DNI, pues aparecerá 00:41:18
en tres líneas, tres registros dentro de la colección 00:41:21
para esa persona. Y por el contrario 00:41:24
podría ser al contrario. Quiero identificar 00:41:27
los clientes que tengo 00:41:29
pero no me preocupa tanto 00:41:33
si vienen más o menos veces, sino 00:41:35
saber todos los que vienen. Pues esa colección 00:41:39
podría ser sin repetidos. Entonces, combinando 00:41:42
estas dos cosas, lo que haremos será crear 00:41:45
objetos de una colección o de otra se puede eso se puede enfocar desde poco estos dos criterios 00:41:48
se pueden enfocar desde diferentes puntos de vista yo como siempre me ha resultado más claro lo decía 00:41:59
el otro día es los que no admiten duplicados son aquellos son los que aquí os habla como conjuntos 00:42:05
el 9c y por aquí en la parte de colecciones esta parte derecha es colecciones esta parte de 00:42:12
izquierda es mapas, es una visión parcial de la posibilidad de colecciones y mapas, hay más que 00:42:19
estas, pero bueno, es más o menos representativo, son los más utilizados. Pues a la derecha que 00:42:25
tenemos las colecciones, aquellos que no permiten duplicados son los que aparecen con set, por aquí. 00:42:31
Y luego tenemos los que no aparecen con set, es decir, este no admite duplicados, el hash set, 00:42:39
el triset tampoco, el linked has set tampoco, admiten duplicados. 00:42:45
Y luego los que admiten duplicados, 00:42:50
pues bueno, aquí aparece la ArrayList y hay algún otro, el LinkedList. 00:42:54
Hablaremos un poco de los dos, 00:43:00
si no es hoy, el próximo lunes. Y luego, 00:43:01
en cuanto al criterio de orden, normalmente si tenemos 00:43:06
un orden funcional porque queremos que esté ordenado, yo que sé, 00:43:09
que deciros, si son objetos de la clase persona, en un programa 00:43:13
podemos querer que estén ordenados alfabéticamente según el apellido. 00:43:17
Pero en otro programa, aunque sea la misma clase persona, igual queremos que estén 00:43:21
ordenados por el nombre. Y en otro, igual lo que nos interesa 00:43:25
es un orden, pero en función de edad de más jovencito, 00:43:29
los recién nacidos con cero años, hasta los más mayores, 150. 00:43:33
O al revés, igual nos interesa ordenados de los más mayores, desde los que 00:43:37
tienen 150 hasta los que tienen cero añitos. Pues si 00:43:41
hay un criterio que queremos nosotros aplicar funcional a esa colección 00:43:45
para que tenga aplicado ese orden, son los que aparecen con tree. 00:43:49
Tree son los que están ordenados. En principio los ArrayList 00:43:53
no tienen orden de ningún tipo y estos, los LinkedHash 00:43:57
mantienen el orden de según se vayan insertando. Este que es el primero que 00:44:01
inserto, el primero que está en la colección. El segundo, el segundo que está en la colección. 00:44:05
pero es simplemente un orden de inserción y no tanto 00:44:09
un orden definido según un criterio de nuestro 00:44:12
programa, que esos son los TRI. A grandes rasgos 00:44:15
no me preocupa ni ordenar 00:44:19
ni ordenación, ni que haya repetidos. Ya está, es 00:44:20
un cajón de salse donde voy guardando la información 00:44:24
que vayan repitiéndose sin orden. ArrayList 00:44:26
en lo que aparece aquí en el dibujo 00:44:31
o linked list 00:44:37
luego hablamos de ello 00:44:39
bueno 00:44:45
a ver, las pilas 00:44:46
las pilas LIFO 00:44:50
los linked has set, dices 00:44:51
los linked list 00:44:54
bueno 00:44:56
en tanto en cuanto 00:45:06
se los va guardando 00:45:10
en las pilas 00:45:11
los LIFO y los FIFO 00:45:14
una pila 00:45:15
y otra la típica fila esta 00:45:18
del supermercado 00:45:20
al que vamos que el primero que atiende es el primero que llega 00:45:21
o la pila que el último que llega 00:45:23
es el primero que se atiende 00:45:25
sí que siguen un criterio 00:45:26
de ordenación según van entrando 00:45:29
pero según los vas recuperando 00:45:31
se van eliminando 00:45:33
digamos que 00:45:35
tiene cierta similitud pero tiene alguna 00:45:36
funcionalidad más añadida 00:45:39
a la hora de recuperar tú recuperas 00:45:40
si es una pila el de arriba 00:45:43
y en un nickel list 00:45:45
podrías recuperar cualquier otro 00:45:47
de la lista 00:45:49
pero en el momento de irse ordenando sí que esos dos que dices y el link el dis tienen un criterio 00:45:50
de ordenación de inserción según se vayan ordenando se van colocando pero a la hora de recuperarlos 00:45:56
quizás no tanto necesariamente y aquí a la izquierda en este lado tenemos los mapas y 00:46:04
a la izquierda perdones a la derecha tenemos las colecciones y la izquierda los mapas y los mapas 00:46:12
la característica que tienen es que trabajan con pares, ¿vale? 00:46:17
Entonces tiene una clave y tiene un valor. 00:46:21
La clave, si pensamos un poco en los arrays y también hablamos de clave y valor, 00:46:26
pues diríamos que el índice en un array podría ser la clave, la posición 5, 00:46:31
pues esa sería la clave del valor que quiero recuperar. 00:46:36
Si es un array de enteros, pues diríamos mi array y entre corchetes ponemos 5, 00:46:38
pues el índice sería 5, que sería un índice de posición en el array 00:46:44
y recupero el valor que es un string o si es un array de personas, la persona 00:46:48
o lo que corresponda. Un poco los mapas serían esa idea. 00:46:52
Accedemos a los diferentes valores según un índice 00:46:56
o una clave que dice aquí y obtenemos un valor 00:47:00
en el mapa. La clave si es por ejemplo entero, pues diríamos 00:47:04
el tercer valor, imaginaos que es 00:47:08
un mapa de personas, ¿no? Pues entonces podríamos decir que la clave 00:47:12
sea el DNI y el valor, todo el objeto 00:47:16
persona en sí, con el nombre, apellidos, nuevamente el DNI podría estar 00:47:20
la dirección, bueno, pues todos los atributos que tenga la clase persona. 00:47:24
Entonces diría, dame de la colección aquel valor que 00:47:28
tenga como clave y ponemos un DNI y que me devuelve 00:47:32
el dato, el objeto de la persona que tendrá ya toda la información 00:47:36
completa de esa persona. Mientras que las colecciones pues tienen un solo dato, no tienen clave y valor, tienen directamente el valor. Y los mapas, es decir, este lado izquierdo, el criterio set, nos olvidamos de él porque los mapas no pueden tener duplicados por clave, la clave tiene que ser única, es decir, digamos que todos los maps serían equivalentes a lo que en las colecciones hemos dicho de set, pero en función de la clave. 00:47:40
y luego eso sí, pueden estar ordenadas o no ordenadas 00:48:09
y las que están ordenadas según un criterio 00:48:12
del programa son las que 00:48:15
vuelven a aparecer por aquí el tree, ordenación 00:48:18
según mi criterio de programa tree, tree map 00:48:21
fijaros este, en cuanto a la colección era 00:48:23
el que estaba ordenado según el criterio de inserción 00:48:29
pues si es según el criterio de inserción la ordenación 00:48:32
del mapa vuelve a ser linked hash 00:48:35
en este caso map y en este caso set 00:48:37
criterio, repito de nuevo, el criterio set 00:48:40
en los mapas no ha lugar, porque nunca habrá duplicado según clave 00:48:45
y el criterio ordenado, que vuelve a ser 00:48:49
la ordenación según la clave, estará 00:48:53
según lo que tengamos definido funcional en nuestro 00:48:57
en nuestro enunciado, de acuerdo a los trimap 00:49:01
y hashmap, pues nada, no tiene ningún tipo de orden 00:49:05
sí que tendrá clave, pero sí que tendrá clave 00:49:08
esa clave nunca podrá estar repetida 00:49:12
pero no tiene ningún orden, el programa 00:49:14
podrá elegir según los guarda, es algo que 00:49:18
es intrascendente para nuestro programa, con lo cual 00:49:21
igual los termina guardando con un orden 00:49:24
como el link de HashMap, pero no te lo garantiza si has definido 00:49:27
un HashMap, entonces vamos a código para ir viendo 00:49:30
todo esto un poco, bueno, otra cosilla 00:49:37
que os quería decir 00:49:39
el otro día me pasó igual no sé dónde está ese gráfico bueno todas las colecciones y ahí bueno 00:49:40
pues según la herencia es conocido la herencia que conocemos todas las colecciones heredan de 00:49:52
o implementan el interfaz java útil colección que es donde nos quedamos el otro día el hecho 00:49:58
de que todas las colecciones me da igual sea la que sea de mapas hablamos luego en otro rato en 00:50:05
otro momento, el lunes que viene 00:50:09
probablemente. Si todas las colecciones implementan 00:50:12
esta interfaz, pues todas están obligadas 00:50:15
a tener descrito qué tienen 00:50:18
que hacer para estos métodos, que son a los 00:50:21
que obliga el interfaz. 00:50:24
Todos ellos hacen lo que nos dice por aquí. 00:50:27
Entonces, cualquier colección, me da igual que acabe en set 00:50:30
porque no tenga duplicados, o acabe en tree 00:50:33
porque tengo una ordenación o directamente sea una que ni tiene ordenación ni nada, 00:50:36
si utilicemos el método site nos tendrá que decir el número de elementos que tiene esa colección. 00:50:43
Si es, por ejemplo, el método add que añade un elemento a la colección, 00:50:49
pues aquí tendrá unas validaciones diferentes si estamos hablando de una que permite duplicados 00:50:55
y una que no permite duplicados. 00:51:01
Si es una de estas que acaban en set o no lo es. 00:51:03
una que acaba en set, dentro de su código tendrá que hacer 00:51:05
la comprobación en todos los elementos 00:51:08
que tiene ya incluidos de si el nuevo elemento 00:51:11
que estoy intentando añadir ya existe. Si existe 00:51:14
¿qué devolverá? Pues devolverá un boolean, dirá false, no he sido 00:51:17
capaz de insertarlo porque ya existe el elemento 00:51:20
y no se pondrá. Si es una colección que admite 00:51:23
duplicados, pues dentro del código 00:51:26
Java que tenemos en las librerías para el método add 00:51:29
de esa clase que implementa una librería con duplicado, una colección 00:51:32
con duplicados, no hará esa comprobación y directamente 00:51:36
lo meterá. Las dos obligatoriamente tendrán que tener 00:51:40
el método ADD porque las dos implementan el interfaz Java 00:51:43
UtilCollection, pero una hará una cosa y otra otra 00:51:47
en función de la característica que tenga esa colección en particular. 00:51:51
Lo cual nos resulta a nosotros muy útil porque el mismo 00:51:57
programa se comportará de una forma o de otra sin tener que programar 00:51:59
nosotros nada adicional, para que tenga o no tenga esos duplicados. 00:52:04
¿Qué métodos tenemos? Que ahora los repasamos un poco 00:52:09
por aquí. Pues fijaros, size nos dice el tamaño, si está vacía la colección, 00:52:12
tiene algún elemento o no tiene ninguno. 00:52:16
Nos devuelve un boolean el método contains diciendo verdadero 00:52:19
si este objeto, este tipo, este elemento ya está en la colección 00:52:23
o no, para incluir un elemento, para borrar un elemento. 00:52:28
Un iterador es algo que nos permite hacer un bucle de todos 00:52:32
los elementos que tiene la colección. Sería como hacer 00:52:35
un while de todos los elementos de un array, pues a través del iterador podemos hacer 00:52:39
esto. Convertir una colección a un array, 00:52:44
decir si en una colección 00:52:50
todos los elementos de otra colección existen. Imaginaros que tenéis una colección 00:52:53
de colores, que tienen 50 colores, entre ellos está incluido 00:52:57
el blanco y el negro. Y tienes una segunda colección 00:53:01
que es blanco y negro solamente. Puedes decir, a ver si 00:53:05
en la colección con más datos existen todos los elementos 00:53:09
que tiene la colección que tiene menos. En este caso, como era blanco y negro y estaba 00:53:14
también en la que tiene más elementos, nos devolverá true. Y en caso 00:53:17
de que la colección pequeña tuviera el blanco, negro y amarillo 00:53:21
y el amarillo no está en la que tiene más elementos, pues nos devolvería 00:53:25
false. Bueno, pues diferentes herramientas con las que 00:53:29
podemos ir trabajando. Añadir todos los elementos 00:53:32
de una colección en otra. Tenemos una colección más grande, 00:53:35
pues intentamos añadir otra colección que tiene menos 00:53:38
o que tiene más los elementos de una colección en una segunda. 00:53:41
Borrar todos los elementos que existen 00:53:44
en una colección en otra. 00:53:46
Esta hace la lógica inversa, solo mantiene 00:53:51
los que no aparecen los que están en la colección al hacer lo contrario y conciliar borramos los 00:53:54
datos de la colección completa vamos a trabajar un poquito algunos de estos datos algunos de estos 00:54:01
métodos que tienen que estar disponibles te digo en todas las colecciones entonces mirad una de las 00:54:11
colecciones que admiten duplicados en la colección y que no están ordenados son la colección a rail 00:54:27
list. Fijaros lo que pongo aquí, que os sonará a lo que poníamos 00:54:32
aquí, ¿verdad? De mi clase esta que había hecho genérica. 00:54:40
Podemos decir que es un ArrayList, por ejemplo, de strings. 00:54:46
Mi ArrayCollection, Call de Collection, y hago un new. 00:54:54
Cuando, típicamente, para que busquéis un poco similitud a lo 00:55:00
que estamos haciendo normalmente, si hacemos un objeto de la clase 00:55:04
persona y pongo mi pair, que lo definimos una referencia a una clase que es la clase 00:55:06
persona. Luego hacemos un new y el constructor de la clase persona. Pues si os fijáis aquí 00:55:12
decimos que definimos una referencia a una clase que es la clase ArrayList y resulta 00:55:20
que esa clase como es genérica le tenemos que indicar un dato. Esta clase ArrayList 00:55:27
que está definida en las bibliotecas de Java, tendrá algo 00:55:32
como esta cuando se está definiendo, donde estamos diciendo 00:55:36
que uno de los datos que recibe es genérico. Y aquí decíamos 00:55:40
luego poníamos new y el constructor persona, pues aquí hacemos 00:55:48
new y el constructor de la ArrayList. 00:55:52
No me compila porque tenemos que importar la clase de Java útil. 00:55:56
Pues ahí lo tenemos. Fijaros 00:56:03
en el contexto de mi ejercicio, resulta que 00:56:06
deduzco, según el enunciado, que necesito empezar a almacenar 00:56:09
valores de tipo string, no sé 00:56:13
la cantidad, con lo cual me he decidido irme por una colección en lugar de por un array, 00:56:18
como no sé la cantidad, no me voy a arriesgar a eso, y 00:56:22
según este contexto, no necesito ni que estén, vale 00:56:26
que estén duplicados los valores y no necesito que estén 00:56:30
ordenados, porque he hecho un ArrayList 00:56:34
el nombre que tiene ese Array 00:56:37
es miArcCol 00:56:42
y justo 00:56:43
no voy a necesitar 00:56:45
definir 00:56:47
dentro de las librerías de Java 00:56:48
un montón de clases ArrayList 00:56:51
no voy a necesitar definir una ArrayList de String 00:56:53
y otra que sea 00:56:55
ArrayList 00:56:58
de Integer 00:56:59
no voy a necesitar esto, ¿por qué? 00:57:01
porque estoy haciendo 00:57:03
que los datos con los que trabaja, que esa clase 00:57:05
sea genérica y se lo indico aquí. Entonces podría definir una ArrayList 00:57:07
de Integers y otra de Strings. Que si solamente 00:57:10
trabajásemos, os decía el otro día, con los tipos primitivos, a lo mejor no sería 00:57:15
descabellado no hacer la genérica y hacer 10 clases ArrayList 00:57:18
y tenerlas en las librerías. Podríamos permitírnoslo para Integer, para 00:57:22
Non, para Boolean, para... Pero tened en cuenta que las colecciones 00:57:27
luego tendremos una ArrayList que será para 00:57:30
de objetos de la clase persona. 00:57:34
Y en el momento en el que entramos ya en la dinámica de clases 00:57:37
que definimos nosotros en nuestro programa, 00:57:40
esto ya se convierte en algo infinito, 00:57:42
porque habrá clases en unos programas que sea la clase persona, 00:57:44
en otra que sea la clase gato, 00:57:46
en otra que sea la clase para las personas, 00:57:48
ya se convierte en algo infinito 00:57:50
y no podemos tener en las librerías infinitos ArrayList. 00:57:53
¿Cómo lo solucionamos? 00:57:56
Con un código único donde el tipo con el que va a trabajar 00:57:56
esa colección se lo indiquemos de forma genérica. 00:58:01
es decir, es súper útil en este caso 00:58:04
este concepto. Este es el motivo por el que hemos estado 00:58:08
antes durante la primera parte de la tutoría entendiendo cómo funcionan 00:58:12
las clases genéricas. 00:58:16
Los ArrayLinks, ¿qué son? Son colecciones y como son colecciones 00:58:21
implementan el interfaz Collision y si implementan 00:58:24
el interfaz Collision o están mal los apuntes 00:58:28
o mal la librería, o tendremos que tener disponibles todos estos métodos. 00:58:32
Vamos a empezar trabajando con el método add, vamos a insertar algún elemento. 00:58:38
Entonces ponemos aquí, miArcCall.add, 00:58:44
clic, sé que es un id listo, pues ya nos dice que este add está esperando un string. 00:58:51
¿Por qué? Porque aquí hemos dicho que esto es un string. 00:58:59
Entonces cojo y le meto aquí, hola. 00:59:05
o le meto una, vamos a definir una variable. 00:59:09
Le puedo poner el string directamente o 00:59:24
voy a volver a añadir la misma, voy a añadir la misma otra vez 00:59:26
y ahora voy a poner aquí un system.out 00:59:35
println y otro de los métodos 00:59:51
que nos dice que tenemos aquí, ¿verdad? Es el método size. 00:59:58
Número de elementos que tiene la colección. 01:00:02
Entonces cojo y digo mi 01:00:11
ar.col.size. Entonces hago aquí 01:00:12
una ejecución y me dice que tiene tres elementos. Fijaros, 01:00:19
1, 2 y 3, 3 ADD que hemos hecho. Fijaros, si yo esta colección en lugar de una ArrayList decido que es una HashSet, vamos a decir que es una HashSet, las Set decimos que no tienen duplicados, ¿verdad? Entonces digo que me la incorpore, las HashSet no admiten duplicados, entonces si yo ahora ejecuto aquí, ¿cuántos elementos me dice que tiene? 2, en lugar de 3, ¿qué he hecho? He hecho 3 ADD, pero este es el mismo elemento, ¿no? 01:00:22
Como es el mismo elemento, resulta que solamente me lo ha puesto una vez y esta me la ha puesto dos veces. 01:01:15
El método ADD, fijaros por aquí, como nos dice que el método ADD devuelve un boolean que dice si permite añadir el elemento a la colección. 01:01:22
Entonces si yo cojo y lo que me devuelve el método ADD, voy a aprovechar y lo voy a meter aquí en un system.out.println. 01:01:41
simplemente voy a sacar lo que me devuelva el System.out, el ADD 01:01:49
ahí tenemos, son las mismas transacciones que hacíamos antes 01:02:07
añadir tres elementos a la colección, pero lo que me devuelve él lo voy a sacar 01:02:14
por pantalla, que es un Boolean, acordaros, entonces yo si vuelvo 01:02:18
a la ArrayList de nuevo, pues me dice true, true, true, y que tiene tres elementos 01:02:24
true, cada uno de los ADD me ha devuelto verdadero, y si cojo 01:02:30
y me voy al HashSet, me dice true, esta la añade 01:02:34
efectivamente está vacía, tiene su lógica, este me dice false, lo quita y este coge y me dice que lo añade 01:02:42
también, true false true, me dice que tiene dos elementos, si hacemos un clear por ejemplo por aquí 01:02:48
y vuelvo a mostrar el tamaño, me dice true false true que tiene dos elementos y después del clear 01:03:00
el tamaño es cero, ¿por qué? porque lo ha vaciado, tiene dos elementos porque mantenemos el hash set 01:03:12
que nos admite duplicados, si yo ahora ejecuto por aquí, pues fijaros 01:03:17
me mantiene los tres elementos y luego después de clear, pues vuelve a tener 01:03:26
cero, por aquí tenemos el triset, ahora después miramos 01:03:30
el criterio, vamos a hacerlo con linked 01:03:41
hash set y con triset, linked hash set y triset 01:03:45
para entender bien la diferencia también que os comentaba 01:03:49
hacemos linked 01:03:54
set, vamos a poner aquí 01:03:59
treset, ahora comentamos una de ellas 01:04:19
y vamos alternando entre una y otra 01:04:21
treset 01:04:23
meto la, le importo 01:04:24
desde java útil y el treset también 01:04:32
mirad, otro de los métodos 01:04:34
ahora vamos al link de haset y al treset 01:04:47
os comento antes otra cosa 01:04:49
otro de los métodos que tenemos por aquí 01:04:50
bueno, recorrer las 01:04:53
colecciones, bueno, tiene 01:04:55
diferentes formas, una de ellas 01:04:57
para recorrer todos los elementos 01:04:59
es a través de 01:05:00
una clase que es la clase iterator, también se puede hacer con un for, luego hacemos algún ejemplo con el for también, entonces toda colección al implementar esta interfaz tiene el método iterator, fijaros que devuelve un objeto de la clase iterator que a su vez es genérico, como podemos hacerlo esto, pues mira para esta colección, voy a comentar este para que tenga datos, por aquí, yo puedo definir un objeto de la clase iterator, 01:05:02
que es también genérico, como hemos estado viendo 01:05:32
en los otros casos. 01:05:35
A ver, ¿dónde está el menos más? 01:05:38
No encuentro el menor mayor ahora en el teclado. 01:05:40
Vamos a decir iterator, un iterator de string 01:05:47
y decimos que sea miIter. 01:05:49
Y ese objeto de la clase iterator, 01:05:58
que en principio va a ser un iterador, 01:06:01
algo que va a ir recorriendo diferentes elementos 01:06:03
de tipo string y que hemos llamado miIter, 01:06:06
lo vamos a cargar desde la colección miArrCall 01:06:08
con el método iterator. 01:06:11
Vamos a importarlo, dejaba útil, y el método iterator se parece un poco a, en los métodos que tiene para su manejo, se parecen un poquito a lo que es la clase scanner, a mí me lo recuerda siempre. 01:06:13
Entonces podemos poner un while mientras mi iter.hasNest, mientras haya elementos que ir recorriendo, lo que vamos a hacer va a ser, vamos a coger string ese info, que sea igual, y aquí hicimos mi iter.nest. 01:06:33
voy a coger el siguiente elemento, ese info no le gusta por, he llamado una variable ya por ahí ese info en algún sitio, ese info 2 tampoco, ese iter, ahí está, lo podemos hacer aquí, hacer un system.out.println de ese iter, 01:07:01
Mira, hasta ahora mismo estamos trabajando con un ArrayList que permite duplicados, con lo cual, al principio deberá añadirnos los tres, tendrá un tamaño de tres. 01:07:27
Luego defino un objeto de la clase iterator, que es, le he puesto string aquí porque estamos trabajando con un ArrayList de strings, si fuera un ArrayList de personas, ahora trabajamos con uno de personas o de otro tipo. 01:07:40
pondríamos que el iterador, cada uno de sus valores, que mi iter en cada una de las 01:07:56
vueltas sea de la clase persona, luego 01:08:00
después, ahora de momento string, y llamamos al método iterator 01:08:04
de miar, que recordad, es una colección de tipo 01:08:08
ArrayList, pero sea del tipo que sea, lo tendríamos disponible 01:08:12
porque es una de las que están definidas en el interfaz 01:08:16
colección. Y lo que hacemos es, cuando se genera el iterador 01:08:20
digamos que se pondría en el primero de los elementos de la colección apuntándolo 01:08:26
dice ¿quedan todavía elementos que recorrer dentro de la colección según 01:08:30
apunta el iterador? Si es hashNest igual que el escáner nos 01:08:34
devolvería un true. Entonces como quedan hago 01:08:38
un nest que lo que hace es leerle ese valor y esto 01:08:42
devolverá al que está apuntando que en principio será una variable 01:08:46
de tipo string. Aquí trabajamos con ella según dijese nuestro enunciado 01:08:50
solamente lo vamos a mostrar por pantalla, y el puntero del literador a la colección avanzará al segundo de los elementos. 01:08:54
Como tenemos tres, todavía habría elementos en el bucle, cogería ese segundo, al coger el segundo lo vuelve a cargar en esta variable, 01:09:01
y el puntero que está identificando el elemento en el que está el literador dentro de la colección avanzaría al siguiente, el tercero. 01:09:10
Aquí lo mostraríamos por pantalla, haríamos la misma jugada con el tercero y al coger ese tercero intentaría apuntar al siguiente que ya no existirá y como no existe el hashnet devolverá falso y nos terminaría el programa. 01:09:17
Esta es un poco la idea. Es algo parecido a recorrer un array elemento a elemento. 01:09:31
Fijaros cómo efectivamente nos dice hola, hola y adiós. 01:09:38
un ArrayList, aunque se supone que no tiene ningún orden, en principio lo está guardando 01:09:43
igual que lo haría un LinkedHashSet, según el orden 01:09:48
en el que están guardados. Bueno, lo ha hecho 01:09:52
pero si lo defines como un ArrayList, es verdad que aquí no lo ha mostrado así 01:09:56
pero si en una ejecución, por lo que sea, la máquina virtual de Java 01:10:00
decidiese ponerlo de forma desordenada, no podríamos culpar a nuestro programa 01:10:03
porque lo hemos definido con un ArrayList que se supone que no tiene por qué estar ordenado 01:10:08
si queremos tener garantías de que está ordenado 01:10:11
y si que nos podríamos quejar de que la máquina virtual lo ha hecho mal 01:10:15
sería si le hacemos un linked hash 01:10:18
bueno, claro, el linked hash set no nos va a permitir 01:10:22
duplicados ya, un hash set 01:10:25
un hash set, este no nos permitiría 01:10:28
duplicados, pero tampoco ningún orden 01:10:32
mirad, un linked hash set se supone que 01:10:34
están ordenados según el criterio de inserción 01:10:40
y no permite duplicados, porque es un set. 01:10:43
Entonces, cogemos y le damos aquí. 01:10:49
Fijaros, según orden, criterio de entrada, hola y adiós. 01:10:51
Y ahora me muestra dos elementos en literador. 01:10:56
¿Por qué? Porque este está duplicado. 01:10:59
Este no lo ha añadido. 01:11:02
Este que corresponde a esta entrada. 01:11:04
Y si lo defino como un triset, pues seguirá un orden, 01:11:11
un criterio de ordenación según identifiquemos nosotros. 01:11:15
Vamos a ver qué es lo que hace aquí el programa. Fijaros, aquí mostraba hola y adiós. Y aquí nos dice que el resultado de recorrer el iterador es adiós, hola. ¿Y cuál es el motivo? Pues el motivo es que la ordenación la ha hecho según el criterio que está definido para el tipo de esta colección, string. 01:11:18
Y normalmente, ¿cómo tenemos definidos los string? Los tenemos definidos de forma alfabética, con lo cual, a la hora de ir insertando esos datos, aunque a Dios lo hemos insertado después, por tratarse de un triset, lo ha colocado en primer lugar y luego después hola. 01:11:39
Como es tree, ha utilizado un criterio funcional para ordenarlos. Primero adiós, luego hola, criterio alfabético, ¿verdad? Al ser un string. Y al ser set, en el tree set, pues ha evitado duplicados. De los tres ha metido dos solo. 01:11:56
Mira, los tipos primitivos, los tipos primitivos lo que tienen es, ya tienen implementado, los tipos primitivos, las clases grupper de los tipos primitivos y los tipos primitivos tienen definido ya un criterio de ordenación preestablecido. 01:12:13
entonces si es un string, el criterio que consideran es alfabético 01:12:37
pero si es un entero 01:12:41
pues es numérico de abajo arriba, el 0 el primero 01:12:45
el 1, el 2, el 3, es el criterio que utilizan 01:12:49
pero en nuestro programa podríamos tener criterios diferentes, entonces vamos a crear 01:12:52
bueno, alguna duda antes de seguir contando más cosas 01:12:57
por no contaros, contaros si hay algún problema ya por ahí en algo 01:13:02
fijaros lo cómodo que es utilizar la librería de Java 01:13:05
porque el mismo código 01:13:11
según tengamos en nuestro enunciado 01:13:13
identificado según diferentes requisitos 01:13:16
lo único que tenemos que hacer es 01:13:19
definir colecciones distintas 01:13:20
las colecciones son súper útiles 01:13:23
en verdad se utilizan mucho 01:13:26
¿alguna dudilla por ahí tenéis? 01:13:28
o sigo contando cosas 01:13:36
si no me paráis sigo 01:13:37
¿Vale? ¿Alguien levantaba la mano por ahí? No. Pues nada, pues sigo contando dos cosas. 01:13:39
Mira, vamos a dar un paso más. En lugar de hacer una colección de strings, vamos a hacer una colección de personas. 01:13:50
Vamos a hacer una colección, vamos a hacer un triset de personas. Luego alternamos con otras. 01:14:12
aquí tenemos, voy a definir dos personas 01:14:18
miper1 y miper2 01:14:34
digo, miar call, nombre de la colección, punto, add 01:14:38
y fijaros como ahora el IDE me dice, oye, que lo que tienes que añadir son personas 01:14:48
¿por qué? pues porque he definido que esta colección es de personas, súper útil 01:14:52
el tema de la posibilidad de definir clases genéricas 01:14:56
útil e imposible gestionarlo de otra forma 01:15:01
Vamos a añadir dos veces la misma persona, igual que estábamos haciendo antes con los strings, y una segunda vez esta otra persona. 01:15:04
Y luego vamos a mostrar aquí el tamaño. 01:15:13
Fijaros, me ha pegado aquí un fallo y me dice algo aquí de comparable. 01:15:30
¿Veis aquí en el error? Dice, oye, que yo no puedo, no tengo definido de ninguna forma. 01:15:36
Fijaros que he creado una colección triset. 01:15:43
Las colecciones triset no admiten duplicados y tienen que estar ordenadas. Y claro, aquí viene la pregunta ahora. Oye, ¿y cómo considero yo que dos personas es la misma persona? ¿Y cómo considero yo el orden? 01:15:47
Porque habrá una clase en la que la clase persona tendrá el DNI y otra en la que no. 01:16:03
Que a lo mejor podría ser un criterio para que no haya duplicados. 01:16:10
Pero a lo mejor en mi ejercicio, aunque estamos acostumbrados, bueno, por lo menos administrativamente, 01:16:13
a tener un DNI cada uno, ¿verdad? 01:16:17
Que en un trised podría ser, seguramente sería uno de los criterios que utilizaríamos habitualmente 01:16:20
para que sean las mismas personas. 01:16:24
Pero resulta que es que en mi ejercicio no me importan los DNIs. 01:16:26
yo lo que quiero es que no haya 01:16:30
en mi tienda 01:16:33
es una situación un poco extraña 01:16:34
pero para intentar buscar un ejemplo 01:16:36
que en mi tienda no haya más de una persona que sea 01:16:38
rubia y no haya más de una persona que sea 01:16:40
morena y no haya más de una persona que sea 01:16:42
pelirroja, entonces si vienen 01:16:44
cinco pelirrojos, por mucho que 01:16:46
tengan diferentes DNI 01:16:49
ese no es el criterio de repetición 01:16:51
que tengo yo en mi ejercicio, el criterio de 01:16:52
repetición que tengo yo es que sea pelirrojo 01:16:54
en el momento que hay un pelirrojo no puede haber un segundo pelirrojo 01:16:56
en el momento que hay un moreno, un rubio 01:16:59
o como sea. Entonces el criterio de gestionar los duplicados puede ser diferente en cada uno de los ejercicios. Eso en cuanto a los duplicados, si resulta que es un set y el criterio de ordenación, ¿cuál es? Si es una persona, si resulta que a lo mejor tiene atributo de edad y tiene atributo de apellidos, oye, mi colección va a estar ordenada alfabéticamente por el primer apellido y si son iguales por el segundo 01:17:00
o va a estar ordenada por la edad o por el DNI, un orden de DNI, pues en cada ejercicio puede ser diferente también. 01:17:28
La colección, en el momento en el que vaya trabajando para ordenarlo, fijaros que es la colección triset 01:17:37
y tiene que valer el orden para un triset para cualquier tipo que tengamos por aquí, 01:17:44
con lo cual tendrán que buscar un punto común que exista en todas las posibles clases 01:17:50
para las que le vayamos a meter aquí un tipo genérico 01:17:56
y que nos garantice que da igual el tipo este termine 01:18:00
ordenando y considerando que no es repetidos. 01:18:04
Y por aquí me chiva, oye, no me gusta porque no está implementando 01:18:08
el interfaz comparable. Entonces, si yo pongo aquí en la clase persona 01:18:12
un implements comparable 01:18:16
y añado los 01:18:22
métodos que están sin implementar, el método que me pone 01:18:26
es el método compareTo. ¿Qué nos hace pensar esto? 01:18:31
Que el triset, para ver cómo ordena 01:18:35
las personas que están en esa colección, y el triset 01:18:39
para ver si dos personas están repetidas, el método 01:18:43
que va a utilizar va a ser el método compareTo. Entonces, 01:18:47
todas las clases, todos los 01:18:51
tipos de colección triset que queramos poner aquí, obligatoriamente, tendrán que tener el método compareTo, que es el que me obliga 01:18:55
al interfaz comparable. Bueno, esto u otro mecanismo que veremos alternativo, pero de momento vamos por aquí. Tendrán que tener implementado 01:19:04
el interfaz comparable para tener posibilidad de ordenar y ver duplicados. 01:19:13
Y ahora aquí ya en la clase persona, sí que tengo yo aquí una zona de código 01:19:24
donde voy a poder gestionar si dos personas son iguales para evitar repetidos 01:19:29
y con qué criterio quiero yo ordenarlos. 01:19:34
Aquí podría decir, quiero ordenar por edad, quiero ordenar por primer apellido. 01:19:37
dos personas que son iguales son las que dos personas que tienen el color de pelo rubio dos 01:19:40
personas que son iguales son dos personas que tienen el color de pelo moreno o dos personas 01:19:46
que son iguales son aquellas que tienen el mismo dni según el criterio particular que tenga mi 01:19:51
ejercicio me ha anunciado que porque más funcionado antes el ejercicio cuando he puesto yo aquí 01:19:57
tristez con string no me ha dado este error y me ha dicho oye el método comparable el 01:20:05
interfaz comparable no lo tienes definido pues porque resulta que string es un tipo de los que 01:20:10
están en las librerías de java que si nos fuésemos a ver su código en las librerías efectivamente 01:20:16
tiene implementado el método con el interfaz comparable y el método compare tú con lo cual 01:20:21
la colección se ha apoyado en ese método del string y la válido mira si yo ahora cojo y ejecutó el 01:20:26
programa, ya con el método compare tú en la clase persona, me dice que hay una sola persona, que ha metido una sola persona. He hecho tres ADDs, ¿verdad? Dos veces la misma y una persona diferente. Y me dice que hay una sola persona. ¿Por qué hay una sola persona? Pues porque el método compare tú devuelve un cero cuando las dos personas son iguales. 01:20:33
devuelve un valor mayor de 0 cuando una de las dos personas es mayor 01:21:02
que la otra y un valor menor de 0 01:21:06
cuando es la otra persona la que es mayor. Aquí ahora mismo 01:21:10
como pone return 0, compare tú, está devolviendo siempre 01:21:15
0 y como devuelve siempre 0, considera las dos personas 01:21:19
iguales. ¿Cómo podemos estar seguros de que se está llamando a este método 01:21:23
en el momento en el que estamos añadiendo aquí elementos? Voy a dejar solamente 01:21:27
dos aquí. Y voy a ejecutar y a pesar de que son 01:21:32
personas diferentes, observad cómo me añade solamente una. 01:21:36
Y ahora tenemos que hacer un acto 01:21:41
de fe diciendo, vale, me estás contando que después de meter el interfaz, 01:21:44
el criterio que utilices es el compare to para ver que las dos personas 01:21:48
son iguales y por eso pone solo uno. Pues mirad, podemos poner aquí 01:21:52
un system.auth.println 01:21:55
Vamos a poner aquí, paso por aquí. Fijaros que nuestro código a la vista, no estamos llamando al método compare tú de la clase persona en ningún sitio, ¿verdad? Lo único que hacemos es el constructor y ya está, y luego añadirlas. 01:22:01
Pero si ejecutamos, fijaros cómo efectivamente en el momento en el que hacemos el ADD en las librerías de Java, se va a los objetos de la clase Persona y utiliza el método compareTo, fijaros cómo nos ha mostrado dos veces aquí la traza que hemos puesto, para ver si las dos personas son iguales. 01:22:21
¿Por qué ha considerado que las dos personas 01:22:41
estas son iguales? Pues porque el compareto 01:22:44
está devolviendo un cero, que es el criterio que tenemos para que dos personas 01:22:47
sean iguales. Mira, si pongo aquí un uno, ¿qué hace? 01:22:50
Me añade las dos personas. ¿Veis el size aquí? ¿Por qué? 01:22:58
Porque ya esas dos personas no son iguales, son diferentes. 01:23:00
¿Qué es lo que devuelve el compareto? 01:23:04
¿Vamos bien? Vamos a definir aquí dos atributos, 01:23:11
la edad y el nombre, 01:23:27
dentro de la clase persona. 01:23:29
Mira, para esta primera persona vamos a decir que se llama, que se llama, y la segunda persona, que se llama. 01:23:37
En principio queremos que el criterio de ordenación sea de forma ascendente para las personas según su nombre. 01:24:06
Esta primera persona hemos dicho que se llame Agus, esta segunda persona que se llame Miguel. 01:24:16
Entonces lo que puedo hacer aquí es poner el criterio codificado que a mí me interese en el compare tú. 01:24:20
entonces digo 01:24:27
las dos personas que se están comparando 01:24:28
en este compareTo es 01:24:31
el objeto que llama al compareTo 01:24:32
y el objeto que se recibe por aquí 01:24:35
como parámetro 01:24:37
alguien estará haciendo desde las librerías de Java 01:24:37
una llamada al método compareTo 01:24:41
de la clase persona 01:24:43
no sé cómo lo estará organizando 01:24:44
pero a lo mejor 01:24:47
miPer está llamando a la clase compareTo 01:24:49
pasándole 01:24:51
como atributo al compareTo 01:24:52
miPer2 01:24:54
entonces aquí podemos coger y decir 01:24:55
persona per house 01:24:59
vamos a poner, vamos a decir, vamos a hacer un casting 01:25:03
porque fijaros que esto recibe un object 01:25:06
para decir que sea una persona 01:25:09
con lo cual la referencia de la segunda persona 01:25:12
que la estamos recibiendo como un object 01:25:16
hacemos un casting para poder trabajar con ella como una persona 01:25:18
y ahora decimos if, si la persona que está llamando 01:25:21
y decimos dis.eseNombre 01:25:25
como es un string 01:25:29
tendremos que utilizarlo para compararlo con compareTo 01:25:32
compare, mira, el método compareTo 01:25:35
devuelve un entero 01:25:40
y bueno, y por aquí 01:25:50
si no leemos todo esto, dice que si las dos 01:25:52
string, como es la cadena string 01:25:55
son exactamente iguales, devuelve un cero 01:25:58
Aquí no lo dice. Son exactamente iguales. Y si una es mayor que otra, alfabéticamente devuelve un valor mayor que cero y si la otra es mayor, devuelve un valor menor que cero. Aquí lo cuenta. 01:26:01
Entonces decimos, si una de las personas, punto, compare tú, respecto al nombre de la otra persona, per aus, punto, ese nombre, si esto es mayor que cero, pues querrá decir, ahora mismo no sé justo el orden, que esta persona es mayor que esta. 01:26:16
vamos a hacer un primer amago, si no luego cambiamos el código 01:26:44
y valor devuelto 01:26:46
vamos a poner aquí que sea 0, vamos a inicializarlo a que las dos personas fuesen igual 01:26:52
entonces si 1 es mayor, decimos que 01:26:56
y es igual a 1, si es la otra persona la que es mayor 01:27:00
devolverá un valor menor que 0, con lo cual vamos a poner aquí un menos 1 01:27:11
y vamos a decir aquí que devuelva y valor def 01:27:15
recapitulamos lo que estamos haciendo aquí en este ejercicio 01:27:21
fijaros, las dos personas que están comparando 01:27:25
una es la que está llamando al método compareTo 01:27:28
que le identificamos con this, recordad 01:27:30
que lo hemos hecho en los constructores 01:27:33
y la otra es la que está recibiendo como atributo 01:27:34
aquí, en el método compareTo 01:27:38
esta persona, hacemos un casting de tipo persona 01:27:40
con perraus y ahora comparamos las dos 01:27:44
las strings, acordaros que no las comparamos con igual, igual o mayor 01:27:47
o diferente, sino que lo utilizábamos con equals o con compareTo. 01:27:51
Y aquí comparamos. El nombre de esta persona comparada con esta 01:27:55
me devuelve un valor mayor que cero. Esto me identifica que una de las dos 01:28:00
es mayor que la otra. Si es la otra la que es mayor, me devuelve un valor menor que cero. 01:28:04
Y si devuelve cero, no entra ni por aquí ni por aquí el compareTo 01:28:09
y es a lo que lo tenemos aquí inicializado. En caso de que sean las dos iguales, 01:28:12
me devolvería un valor de cero. 01:28:16
Vamos a ejecutar, una persona se llama Agus y otra se llama Miguel, ese nombre es Nur, vale, si lo que ha sucedido es que estoy haciendo aquí un ADD fijaros antes de asignarle valor y aquí igual, con lo cual si haciendo esto lógicamente todavía no tienen información los nombres, vamos a poner aquí los ADD justo después, ahora ya aquí en este momento ya ambas personas tienen nombre, 01:28:21
Yo creo que no debería pasar esto ya. 01:29:18
Entonces ejecutamos. 01:29:21
Vale. 01:29:24
Me dice que el tamaño es 2 y ahora lo que vamos a hacer va a ser 01:29:25
un iterador para que nos muestre en el orden en el que se han ido guardando. 01:29:28
Fijaros cómo he añadido 2 porque hemos hecho 2 add y las dos personas tienen nombres distintos. 01:29:35
Hasta ahí nos gusta. 01:29:43
Definimos el iterador. 01:29:51
el literador no es de string 01:29:54
sino que sea de objetos de la clase persona 01:29:57
y aquí decimos 01:29:59
muéstrame el nombre 01:30:05
entonces ejecutamos por aquí 01:30:07
y me dice que el orden 01:30:12
es ausi miguel 01:30:14
perdón 01:30:15
y me generaos que en mi enunciado dice 01:30:21
efectivamente quiero que esté ordenado por el nombre 01:30:24
pero no quiero 01:30:26
el orden 01:30:27
alfabético 01:30:28
de primero A, la B, la C, la D, sino que lo quiero 01:30:31
en el orden inverso alfabético. ¿Qué podríamos hacer aquí? 01:30:35
Nos vendríamos a la clase Persona y diríamos, cuando el nombre de una 01:30:38
sea mayor que el del otro, en lugar de devolver 1, que devuelva menos 1. 01:30:42
Y en este caso, que devuelva el 1. El criterio de ordenación 01:30:46
lo estamos poniendo aquí. Entonces, voy a ver Ejecuto. 01:30:52
Fijaros cómo ya viene ordenado con Miguel y Agus. Es decir, el criterio de ordenación es el que 01:30:57
estamos aplicando en el método compare tú de la clase persona porque es el elemento con el que 01:31:02
estamos trabajando aquí mira vamos a suponer que el criterio de ordenación que queremos tener es 01:31:12
el de edad otro enunciado me dice oye que no que no que no es alfabéticamente es según la edad que 01:31:20
tengan entonces las personas éstas tendrían una determinada edad vamos a ponerle aquí vamos a 01:31:29
decir que mi per.iedad, este tiene 10 años, mi per.2.iedad tiene, vamos a poner 15. Como el criterio de ordenación 01:31:35
que quiero tener ahora es el de edad, fijaros que el método compareTo está siendo llamado en el ADD de la colección 01:31:52
porque estamos trabajando con un triset. Si fuera un ArrayList no lo llamaría, no le preocupa, ni el orden mete todos. 01:31:59
Ahora después hacemos una ejecución de una ArrayList. Bueno, pues como ahora el criterio es el de la edad, voy a hacer copy de esto y lo modificamos. Decimos, si la edad de 1, este no necesitamos utilizar el compareTo, porque como son números, si la edad de este es mayor que la edad de perAus.iedad, pues que devuelva un 1. 01:32:07
sino que devuelva aquí menos 1. 01:32:56
Y si es al contrario, si es menor, que devuelva un menos 1. 01:33:00
Ahora es la edad el criterio que estamos utilizando. 01:33:07
Entonces damos aquí una ejecución y me dice Agus Miguel. 01:33:14
Agus tiene 10 y Miguel tiene 15. 01:33:18
Pero no, resulta que el criterio que quiero utilizar es 01:33:21
primero que esté en ordenada la colección según los que sean mayores 01:33:24
y de mayor a menor en edad. 01:33:28
Pues entonces, ¿qué haría? 01:33:30
Pues me vengo aquí en el criterio, pues lo cambio. 01:33:31
Digo que devuelvo un valor menor aquí y un valor positivo ahí. 01:33:33
Y si hago la ejecución, en lugar de Agus, Miguel, me ordenará según Miguel y Agus. 01:33:39
Aquí me muestra Miguel y Agus porque es lo que estoy mostrando aquí, claro. 01:33:46
Pues aquí podríamos poner más con edad. 01:33:49
Aquí pongo ese iter.edad. 01:34:00
O una ejecución y me dice Miguel que tiene 15 y Agus que tiene 10. 01:34:07
Si vuelvo al criterio de edad, que fijaros lo estoy programando todo aquí en el compare to, a este otro criterio, el criterio de ordenación sería August con 10 y Miguel con 15. 01:34:10
Y si resulta que las dos personas tienen la misma edad, ¿qué sucede? Pues que, ponemos aquí que los dos tienen la misma edad, fijaros, y al ejecutar, me ha insertado un, como es un triset, ha utilizado el compare tú, ha visto que el criterio que utilizamos para compararlos es el compare tú, la edad, y los dos tienen la misma edad, pues ¿qué ha hecho? Ha insertado uno solo. 01:34:32
sería repetido, solamente quiero en mi ejercicio 01:34:54
que haya una persona de cada edad 01:34:58
en el momento que coincida la edad los considero duplicados 01:35:01
en este caso, como están los dos duplicados 01:35:04
por mucho que uno es miper1 o miper2 y tienen diferentes nombres 01:35:06
como los dos en este criterio denunciado tienen la misma edad 01:35:10
en la colección solo ha metido uno y ha metido el primero de ellos 01:35:13
Agus, que es el primero que ha hecho el ADD 01:35:16
imaginaros que decimos, a ver, yo considero 01:35:18
¿Qué dos personas son duplicadas en mi ejercicio cuando tienen la misma edad y el mismo nombre? 01:35:26
Y en caso de tener la misma edad, quiero que el criterio de ordenación sea por nombre. 01:35:32
Pues entonces cojo y digo, si la edad es igual, sí que me tuneles aquí. 01:35:40
Y ahora aquí es el momento en el que hay empate de edad, pues voy a utilizar criterio del nombre. 01:35:51
Solamente si una edad es mayor que otra, me da igual los nombres. 01:36:04
lo que tenga aquí puesto. En el caso de que los dos tengan 01:36:07
la misma edad, me voy a fijar en el nombre 01:36:10
porque en mi enunciado es como dice que tenemos que utilizar 01:36:13
el criterio. Entonces si hacemos aquí una ejecución, mirad 01:36:16
me dice primero Miguel, los dos, ¿ha habido empate 01:36:20
de edad en este caso? Pues primero Miguel porque 01:36:23
cuando hay empate hemos programado aquí 01:36:26
que sea el que tiene un nombre 01:36:29
alfabéticamente, digamos, mayor. 01:36:32
Aquí, ¿qué se lee cuando hay empate de edad? 01:36:35
Si le cambiamos aquí el criterio, en caso de empate, ¿qué sucederá? 01:36:38
Pues sucederá que me mostrará ahora primero Agus. 01:36:44
Y por mucho que tengamos el mismo nombre, que es el else, cuando hay empate de edad, 01:36:52
como está esto antes por la edad, si no tiene la misma edad, 01:36:56
da igual lo que hayamos puesto ahí en el nombre. 01:37:00
Si pongo que este tiene 15, pues me dice primero Miguel con 10 de edad. 01:37:02
Y si pongo que este tiene 20, como va a estar el criterio de edad antes, 01:37:10
pues ahora me dirá que el primero es Agus. ¿Se entiende? 01:37:14
¿Seguís por ahí? Eso sí, ¿verdad? Vale. 01:37:34
Sí. Bueno, hay dos formas. Una 01:37:46
ya está así y la otra que la veremos yo creo el lunes que viene 01:37:49
porque ya son las 7 y 12, pero que va 01:37:54
al mismo concepto. Es o implementando la interfaz 01:37:58
comparable o haciendo una clase que es 01:38:02
implementando el interfaz comparator y una clase que es comparator 01:38:05
que vuelve a trabajar sobre el compareTo y hay que pasárselo 01:38:10
al constructor de la colección. Pero bueno, como llevará un poquito de desarrollo 01:38:14
el lunes que viene tenemos, yo creo, tiempo para verlo con tranquilidad. 01:38:18
Pero es un poco, es redundar sobre esta 01:38:23
idea. Volvemos un poco 01:38:26
a los tipos de colecciones que tenemos. Cuando 01:38:29
hablamos de tri set estamos es importante el orden y los duplicados porque es set y porque 01:38:33
es tri entonces la forma de hacerlo es implementando sobre la clase sobre la que de la que vamos 01:38:41
almacenando elementos en la colección con el interfaz comparable o una clase que implementa 01:38:47
tu interfaz que es comparator y luego se mete en el constructor de la clase viene a ser las dos 01:38:55
un poco equivalentes. Os la cuento la semana que viene. 01:38:59
Y luego tenemos otras colecciones que son las que tienen el criterio set, 01:39:03
el criterio set sí, pero el criterio tree no. Es decir, no hay orden, 01:39:10
pero no queremos duplicados. Y para manejar estas, los métodos sobre los que se trabaja, 01:39:16
los que tenemos que sobreescribir, si para el tree set es el compare to, 01:39:23
por el interfaz este, en estas otras 01:39:26
sobre los que trabajamos son sobre el método equals 01:39:30
fijaros que equals nos dice si es igual o no es igual 01:39:33
pero sin darnos un orden, no nos devuelve si uno es mayor 01:39:38
que otro, un valor mayor que cero y si es el otro un valor 01:39:41
menor, equals nos dice true o false, pero justo para 01:39:44
los set donde no hay orden nos resulta 01:39:47
suficiente porque lo único que queremos es que no haya duplicados 01:39:50
si nos devuelve true a equals resultará que 01:39:53
no tengo que insertarlo en la colección, y si nos devuelve false, pues resulta que sí 01:39:56
que tengo que ponerlo. Bueno, sobre el método 01:40:00
de equals y sobre otro que es el hashCode 01:40:07
trabajar sobre estos dos métodos. Lo que vamos a hacer nosotros, ya lo cuento la semana 01:40:09
que viene, es mantener el hashCode igual para todos 01:40:14
los casos sin tocarlo, y indicaremos si dos 01:40:18
elementos son iguales para los set que no son 01:40:22
tree, sobreescribiendo el método 01:40:26
de equals. Ya podéis hacer a la idea. 01:40:28
Sobreescribiremos en lugar del compare 01:40:31
to el equals y diremos 01:40:32
si la edad 01:40:34
es igual a la edad del otro, return 01:40:36
true. Si es diferente, return 01:40:38
false. Y ya está. Y las colecciones 01:40:40
que son set, pero 01:40:42
no son tree, es decir, que no admiten duplicados 01:40:44
y no les preocupa el orden, 01:40:46
cuando vayan a 01:40:49
chequear algo, chequearán estos dos 01:40:50
métodos en lugar del método compare to. 01:40:52
Otra cosilla que me quedaba por enseñaros, mirad, simplemente es por terminar de ir justificando las cosas que vamos contando, intentar ver las que son de verdad, mirad, aquí, aunque está más que demostrado que el trised se va basando en estos criterios para la ordenación, porque según íbamos cambiando aquí, iba sacándonos información diferente por aquí, vamos a meterle para tener total seguridad un system of println de pasa por aquí. 01:40:54
Este método, como decimos, no lo estamos llamando, ¿verdad? Pero al ir haciendo añadidos, ir metiendo nuevos elementos, es en el que se apoya la librería de Java. Entonces, si damos aquí, fijaros como efectivamente por ahí pasa para hacer sus comprobaciones según esté programada la librería Java, en la librería Java, el método ADD de la clase Triset. 01:41:27
es decir, está pasando por este compare tú, sí o sí, aquí tenemos las trazas 01:41:48
si en lugar de tener una librería triset 01:41:53
una colección triset, perdón, utilizamos la librería 01:41:56
la ArrayList, la ArrayList 01:42:04
decimos que no le preocupan en absoluto los duplicados 01:42:08
ni nada de nada, de la clase persona, fijaros aquí hacemos 01:42:12
una ejecución y veis como me ha añadido los dos 01:42:16
ni criterios de nada, ni nombres, ni nada. ¿Por qué? Porque los mete en cualquier caso 01:42:20
y en este caso no me muestra esta traza. ¿Por qué? Porque 01:42:25
como no va a hacer comprobaciones de duplicados ni de orden, no necesita apoyarse 01:42:28
en el método compareTo, que nos ha obligado a meter 01:42:33
el comparable. Es decir, el método add de las librerías 01:42:36
de Java, cuando 01:42:41
utilizamos la colección ArrayList, me da igual para el 01:42:45
tipo de datos que sea, no tiene que hacer esas comprobaciones, pues no tiene 01:42:49
accesos al compareto. En la librería de Java 01:42:52
el código del triset, como necesita un criterio 01:42:56
para trabajar con ordenados y duplicados 01:43:00
en lo que se fija es en el compareto, como hemos visto antes con las 01:43:03
trazas. Fijaros que si ahora estas personas, que los dos únicos criterios 01:43:09
con los que estábamos trabajando, resulta que tienen las dos la misma 01:43:13
edad como es una raíz y las dos el mismo nombre aún así a tratarse de una raíz 01:43:17
buenos metal a los dos si retomamos en la raíz comentamos de 01:43:25
nuevo la raíz y volvemos al tríceps cuantos tenemos uno porque porque el 01:43:33
criterio mismo nombre y mirada es lo que estamos aquí de fin bueno ya dice pasa 01:43:41
por aquí y es lo que hemos definido como para que nos devuelva no se sobreescriba 01:43:45
esto y nos devuelve al valor de por defecto que era el 0. ¿Alguna duda tenéis 01:43:50
por ahí que queréis que comentemos antes de cerrar ya por ahí? El próximo día 01:44:01
me preocupo antes de que se grabara la clase, espero que 01:44:04
sí, para subirla. Y el próximo día retomamos aquí 01:44:09
con el otro criterio para las colecciones. Miraremos también 01:44:13
los que no son tree, como trabajando sobre el equals y el hashcode 01:44:18
es el mecanismo que tenemos para que compruebe si hay duplicados 01:44:22
y hacemos alguna cosita con mapas también y bueno con eso más o menos le damos una vuelta a lo que 01:44:26
es el tema alguna pregunta ya tenéis por ahí bueno pues si no tenéis nada vamos cerrando 01:44:32
ya son las 7 y 20 y ya tenéis tarea y para que os entretengáis si podéis sacar un rato 01:44:44
venga para la grabación y que tengáis buena tarde 01:44:51
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
JM
Subido por:
Jose Manuel M.
Licencia:
Dominio público
Visualizaciones:
50
Fecha:
31 de marzo de 2025 - 19:23
Visibilidad:
Clave
Centro:
IES ALONSO DE AVELLANEDA
Duración:
1h′ 44′ 55″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
209.93 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid