20250204Estructuras dinámicas 2 - 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:
Entonces, voy a grabar esta clase. Si habláis, es porque me autorizáis a grabar vuestra voz.
00:00:00
Entonces, ayer estuvimos viendo un poquito de las colecciones y llegamos hasta la list.
00:00:07
La list es una interfaz importante porque, a diferencia de set, admite elementos duplicados.
00:00:12
Puedo insertar varias veces el mismo elemento si quiero.
00:00:20
Si es que no quiero, pues posiblemente deberías utilizar un set.
00:00:23
o siempre que yo quiera
00:00:26
puedo hacerme mi propia lista
00:00:30
que no admita duplicados
00:00:32
en el que cuando hace la add
00:00:34
sobre escribo la add
00:00:36
para que antes de añadir el objeto
00:00:36
antes de llamar la add de la lista oficial
00:00:39
lo que hace es comprobar que no exista
00:00:41
o sea, el hecho que no lo haga
00:00:45
no quiere decir que no se pueda hacer
00:00:47
¿vale?
00:00:49
vosotros podéis hacer lo que os da la gana
00:00:50
solo que hay que programar
00:00:51
tiene acceso posicional a elementos
00:00:52
es decir, que no es necesario que trabaje al principio o al final, puede trabajar también en el medio dándole una posición, etc.
00:00:56
Puede buscar los elementos concretos y devolver su posición en la lista, puede iterar sobre los elementos como todas las colecciones
00:01:04
y puede trabajar con rango de operaciones, o sea que en vez de hacer añade un elemento, añade otro elemento, añade otro elemento,
00:01:11
puede decir añádeme todos estos elementos, por ejemplo, puede añadir una colección de elementos.
00:01:19
Esto se ve aquí. Arrelist, arrelist, arrelist. Esto es vector. Bueno, vector se verá igual. Está un comando addall que pilla una colección. ¿Lo veis? Y aquí le puedo pasar una colección que puede ser un set y meterlo en mi lista. O puedo pasarle una queue y meterla en mi lista. Porque aquí va cualquier colección posible.
00:01:24
este de aquí hará sustancialmente por debajo un iterador
00:01:47
irá iterando en toda la colección
00:01:53
y por cada elemento que pilla lo añadirá a mi lista
00:01:56
y nosotros
00:01:59
esto es un zoom del dibujito
00:02:04
que hemos visto antes
00:02:08
consideramos cuatro implementaciones de list
00:02:09
en particular dos
00:02:14
que son las que estudiaremos un poquito más en profundidad
00:02:15
Y nosotros ahora veremos ArrayList y LinkedList, del que hemos hecho o intentado hacer nosotros una implementación para entender qué hay por detrás. Vector es muy parecido a un ArrayList, pero tiene la ventaja de ser thread safe, o sea que si yo tengo programación multi-threading con varios hilos, pues acceder a un ArrayList puede dar problemas, mientras acceder a un Vector no.
00:02:19
pero esta cosa incluye implica que se hagan unos controles para decir hoy mira si alguien me está
00:02:47
usando alguien que me quiera usar tendrá que esperar su turno y esto hace que el vector sea
00:02:54
más lento entonces si yo tengo un solo hilo de ejecución como es el caso de aquí de todos los
00:02:59
ejercicios que hacemos pues la realista es mucho más práctico que el vector porque es mucho más
00:03:04
eficiente sin embargo si tengo multiplicación multi trading pues el vector pues puede tener
00:03:08
más sentido. Y stack, que es la implementación de la pila, que hereda
00:03:13
de vector y por lo tanto será thread safe esa también, pero será más lento
00:03:17
que esta otra cosa. Pero si lo que yo quiero utilizar es una cola, es una pila,
00:03:21
pues aquí tengo mi implementación. Centrémonos sobre la primera de las dos.
00:03:25
ArrayList es una implementación típica,
00:03:30
venimos de los arrays, antes conocíamos los arrays, existían los arrays, pues
00:03:32
uso un array para implementar una lista, para escondo detrás de un objeto
00:03:37
con sus metoditos todas las operaciones que había hecho hasta ahora con los arrays.
00:03:41
En un cierto sentido, si os acordáis, cuando yo empecé a hacer mi clase ArrayUtils,
00:03:46
pues eso era un prototipo inicial de una ArrayList, ¿vale?
00:03:52
Os empecé a dar pinceladas de estos métodos aquí, estas operaciones que hacemos una y otra vez y otra vez,
00:03:57
¿por qué no las guardamos en una clase y luego usamos esa clase para hacer cosas?
00:04:05
fue un primer paso, un primer intento de hacer esto
00:04:10
luego no podíamos hacerlo, primero porque era una clase estática
00:04:13
entonces no era un objeto por sí mismo
00:04:17
y segunda cosa porque no teníamos las clases genéricas
00:04:20
entonces cada vez que añadía una nueva clase para poderla utilizar allí
00:04:22
tenía que copiar los métodos, cambiarla, era engorroso
00:04:27
pero ahí está, es el futuro, bueno es el pasado, pero me entendéis
00:04:30
se pasa a un array dinámico que aumenta su tamaño
00:04:35
cuando crece la colección de elementos, ¿vale? Arraigo dinámico es lo que crea, ¿vale?
00:04:38
Porque en realidad los arraigos no son dinámicos.
00:04:43
Puede contener elementos duplicados, puede insertar al final o en una posición concreta, ¿vale?
00:04:46
El orden final es importante, ¿vale?
00:04:51
Si yo no inserto en una posición concreta e inserto A, B y C,
00:04:54
pues luego cuando haré el iterator encontraré A, B y C, porque el orden de inserción tiene sentido.
00:04:59
Está claro que si yo pongo A, B y C y luego digo D, pónmelo como segunda posición, pues cuando haré el iterator me dará A, D, porque lo he metido en segunda posición, B, C. Entonces, la posición tiene sentido y es útil. No es que el último elemento que inserto luego lo pueda encontrar en otros sitios como pasará con set.
00:05:05
Aquí tú defines un orden, defines una posición donde ponerla
00:05:27
Y mantener esa posición es importante para la lista
00:05:32
Permite el acceso aleatorio a ArrayList
00:05:35
Porque al ser implementado con un array yo le puedo decir accede a la posición 3
00:05:39
Y como por debajo de un array puede acceder a la posición 3
00:05:43
Pues me accede directamente a esa cosa
00:05:46
Es muy eficiente, lo vimos ayer en los ejemplos
00:05:48
Es muy eficiente cuando accede a mitad
00:05:50
Mucho más eficiente de la LinkedList
00:05:55
la manipulación es lenta
00:05:57
porque es necesaria gracias a muchos cambios
00:06:00
si se elimina algún elemento
00:06:02
principalmente es la eliminación
00:06:04
yo pensaba también en la inserción pero ayer vimos que con la inserción
00:06:06
era bastante rápido
00:06:08
era la eliminación que si
00:06:09
molestaba mucho al array
00:06:12
¿os acordáis? al array list
00:06:13
no está sincronizado, esto quiere decir que no es
00:06:15
thread safe, esto quiere decir que no
00:06:18
no es bueno
00:06:20
si lo uso entre dos threads paralelos
00:06:24
que nosotros no utilizaremos, por lo tanto
00:06:27
si tenéis más interés
00:06:28
sobre profundizar eso
00:06:32
hay un mogollón de páginas web
00:06:34
donde se explican estas cosas
00:06:37
que vosotros seguramente ya tendréis
00:06:38
vuestra favorita porque desde el principio de año
00:06:40
que estaréis buscando varios
00:06:42
recursos en internet como
00:06:44
Stack Overflow
00:06:46
o cosas por el estilo, incluido hoy en día
00:06:48
la inteligencia artificial
00:06:51
y entonces si esta cosa aquí queréis saber más
00:06:52
habláis con Gemini
00:06:55
Y le decís, Gemini, explícame por favor qué es una ArrayList y cuándo lo tengo que utilizar.
00:06:56
Y él estará muy contento de explicártelo una y otra vez.
00:07:02
Si no, vais a este sitio de aquí y aquí explica un poquito de la ArrayList, ¿vale?
00:07:05
En inglés, porque el inglés es el idioma del futuro.
00:07:09
LinkedList.
00:07:14
¿Qué es LinkedList, vale?
00:07:16
Es la implementación de una lista, pero actualmente, pero no pensada como un Array,
00:07:18
sino pensada como objetos que se puedan enlazar uno a otro
00:07:25
tened en cuenta que esta implementación se basa sobre una lista doblemente enlazada
00:07:29
nosotros hemos hecho un link que me permitía ir al siguiente y nada más
00:07:34
mientras que el linked list tiene la posibilidad de ir en un sentido y en el otro
00:07:38
o sea que cada nodo que yo añado le digo cuál es su siguiente
00:07:44
pero le digo también cuál es su anterior
00:07:49
Entonces, el nodo N está enlazado al nodo N más 1,
00:07:52
y el nodo N más 1 está enlazado también al nodo N.
00:07:56
Entonces, cada nodo tiene la posibilidad de recorrer en un sentido o en el otro.
00:08:01
Y esto me puede servir, si os acordáis,
00:08:06
si hicimos un método en el que necesitaba un nodo y el siguiente para remover.
00:08:08
Entonces, para remover un nodo,
00:08:14
yo lo que tenía que hacer es decirle al anterior que saltara directamente al siguiente.
00:08:16
entonces si tengo una lista doblemente
00:08:21
enlazada, busco el elemento
00:08:24
que tengo que eliminar y de aquí puedo acceder
00:08:26
al anterior y decirle que vaya
00:08:28
al siguiente, más fácil
00:08:30
un poquito más complejo
00:08:32
de gestionar, pero vosotros
00:08:34
que sois alumnos perfectos
00:08:36
y que queréis ser programadores
00:08:38
seguramente, como yo os la dije
00:08:40
la posibilidad de poder hacer nodos
00:08:42
en los dos sitios, en casa
00:08:44
este fin de semana, habéis vuelto
00:08:46
a hacer la linked list por vuestra cuenta
00:08:48
con nodos doblemente enlazados.
00:08:50
Sí, sí, ahí está.
00:08:53
O sea, yo creo que la respuesta a tu pregunta es, creo que no.
00:09:23
Tú estás diciendo, ¿puedo hacer una implementación de list
00:09:33
que tenga la ventaja de los dos sin tener la desventaja de los dos?
00:09:37
Creo que no.
00:09:42
Y la razón de por qué no es porque no existe aquí.
00:09:44
Si existiera, lo más probable es que alguien le habría pensado,
00:09:50
había dicho, en vez de usar ArrayList o LinkedList
00:09:53
usa LinkedArrayList
00:09:55
que es la mejor de todas
00:09:57
entonces yo no estaría aquí a explicar
00:09:59
la diferencia entre ArrayList y LinkedList
00:10:01
más te diría, se usa siempre LinkedArrayList
00:10:03
pero es que no lo veo
00:10:05
¿vale? ¿cómo puede hacerlo?
00:10:07
lo mismo que ArrayList
00:10:17
son iguales
00:10:18
lo mismo que cualquier colección
00:10:20
la única cosa es que tú
00:10:21
si estás utilizando un LinkedList
00:10:24
es porque
00:10:26
quieres elementos duplicados
00:10:27
te interesa el orden, por eso no has elegido un set, ¿vale?
00:10:29
Quieres hacer una lista, por eso estás pensando en las listas,
00:10:34
y utilizas LinkedList cuando quieres manipular mucho los objetos.
00:10:38
Si lo que quieres hacer tú es insertar y quitar muchos objetos,
00:10:49
pues posiblemente la LinkedList es útil.
00:10:53
Quiero hacer una gestión de productos, ¿vale?
00:10:55
en el que me llegan materias primas
00:10:59
y yo gasto estas materias primas
00:11:02
para construir productos, ¿vale?
00:11:04
Entonces, sustancialmente,
00:11:06
cada vez que llega un plan de materia prima,
00:11:07
lo añado a una lista de materias primas,
00:11:09
cada vez que gasto una de esas,
00:11:11
la quito de la cosa.
00:11:13
Es constantemente inserta, quita, inserta, quita,
00:11:14
inserta, quita.
00:11:16
Pues posiblemente una linked list
00:11:17
es más útil que una relista.
00:11:18
Más todavía, si tú estás, sostancialmente,
00:11:22
no estás accediendo a las materias primas
00:11:26
al azar, la estás haciendo
00:11:29
ordenadamente
00:11:31
ahora, al revés
00:11:31
imagínate que en vez
00:11:34
tú tienes, insertas alumnos
00:11:37
que a principio de año insertas todos los alumnos
00:11:39
difícilmente lo removes
00:11:41
porque pocos se quitan
00:11:42
desde la base de datos de los
00:11:44
alumnos, y pero tú quieres acceder
00:11:47
a los alumnos en base a su
00:11:49
número de identificador
00:11:50
que es un número secuencial que
00:11:52
representa la posición del array en el que
00:11:54
ha sido metido
00:11:57
Entonces con eso
00:11:58
Es mucho mejor una revista
00:12:00
Porque el acceso aleatorio a la estructura
00:12:01
Es mucho más rápido
00:12:04
Entonces, ¿cuándo se usa una y la otra?
00:12:05
Pues se pueden usar las dos
00:12:08
Independientemente, lo que pasa es que
00:12:09
Si te equivocas, y lo vimos ayer
00:12:11
Con, ¿qué estamos haciendo?
00:12:13
Estamos simplemente mirándolos
00:12:15
Todos, pillándolos todos
00:12:18
Y hemos visto que uno tardaba dos segundos
00:12:19
Y el otro le hemos dado play
00:12:22
Y hemos esperado un minuto
00:12:24
Y todavía no había acabado
00:12:26
Entonces, si eso lo extendes a tu programa,
00:12:27
tenés la razón de por qué cuando le das a un botón
00:12:32
te quedas ahí esperando cinco minutos
00:12:34
porque está haciendo una operación
00:12:35
que habría sido mejor hacerla con otro botón.
00:12:37
¿Puedo yo decir, oye, mira, me implemento
00:12:41
las dos listas?
00:12:48
O sea, yo tengo lista de alumnos como lista rey
00:12:53
el lista de...
00:12:56
cosa como linked list
00:12:58
y luego uso una o la otra
00:13:00
dependiendo de lo que tengo que hacer
00:13:02
sí, pero al nivel de inserción
00:13:03
y quitar, pues lo tendrás que insertar
00:13:06
en los dos o quitar en los dos, entonces es
00:13:08
más lento, a ese punto
00:13:10
no sé qué estás ganando
00:13:11
¿vale?
00:13:13
puede contener elementos
00:13:16
duplicados, puede insertar al final
00:13:18
o en una posición concreta, como todas las
00:13:20
listas, ¿vale? el orden es
00:13:22
importante, mantiene el orden como todas las
00:13:24
listas. Esta implementación
00:13:26
con respecto a relist mejora la velocidad
00:13:28
de manipulación de los objetos, o sea, insertar
00:13:30
y remover, pero empeora el
00:13:32
acceso aleatorio, porque para acceder a la
00:13:33
posición 7, tengo que entrar desde
00:13:35
el principio e ir a la siguiente,
00:13:37
a las siguientes, a las siguientes, a las siguientes, hasta llegar
00:13:39
a la 7, mientras que con la relist accedía directamente
00:13:42
a la posición 7.
00:13:44
No está sincronizada como la relist,
00:13:45
no se usa con threads, se puede
00:13:47
usar como lista, pila o cola.
00:13:50
¿Vale? O sea que si yo esta
00:13:52
aquí la uso
00:13:53
con reglas
00:13:54
mías, pues puedo hacer que la
00:13:57
linked list pueda funcionar como lista
00:13:59
pila o cola
00:14:01
de hecho
00:14:03
si me voy a linked list
00:14:04
si no me equivoco, veis que
00:14:08
linked list tiene pick
00:14:16
tiene pop
00:14:19
y tiene push
00:14:21
que si os acordáis eran
00:14:22
los mecanismos que yo
00:14:24
usaba para hacer una
00:14:26
una pila
00:14:28
o sea que si yo quiero usar una pila
00:14:30
en vez de stack, que es más lento
00:14:32
porque es sincronizado, pues puedo
00:14:35
simplemente crearme una linked list
00:14:38
y olvidarme que existe la get, que existe
00:14:41
la add, en vez de hacer la add
00:14:44
para añadir cosas, uso solo pop
00:14:47
pick y push, de esta forma
00:14:50
si uso solo estos tres métodos, estoy utilizando esta lista
00:14:53
como si fuera una pila
00:14:56
y así si uso otros
00:14:58
cosas como
00:15:03
si uso la add
00:15:04
y la get first
00:15:09
yo creo que está creando
00:15:10
una cola
00:15:12
add me lo añadirá al final
00:15:14
get first siempre me pilla el primer elemento
00:15:16
entonces usando
00:15:19
los correctos
00:15:22
los objetos correctos
00:15:24
puedo utilizar
00:15:25
una linked list como si fuera
00:15:27
cosa fijaos que en vez del rey list no debería tener si no me acuerdo mal push pop veis esto
00:15:29
no lo puede usar como una como una stack con una una pila si queréis saber algo más pues vais aquí
00:15:41
le es lo que está aquí comparación entre a rey liste linked list vale a rey listos internamente
00:15:51
una red dinámico linked list usa una lista doblemente enlazadas parecida a la que hemos
00:15:58
hecho nosotros pero con dos punteros o sea que el nodo tendrá tres campos tendrá el campo valor
00:16:03
siguiente y anterior siguiente interior son nodos también la manipulación con la relista es lenta
00:16:09
porque internamente susana rey vales es el elemento era rey todos los bits se tendrá que desplazar en
00:16:19
memoria un caos bla bla bla bla la manipulación con linked list es más rápida porque que realista
00:16:24
Porque utiliza una lista doblemente vinculada y cuando elimino algo es simplemente cambiar un puntero y fue a funcionar.
00:16:31
Una clase relist puede actuar como lista porque solo implementa list, ¿vale?
00:16:38
Mientras que una linked list puede actuar como una lista, pero también una cola y también una pila, ¿vale?
00:16:43
Si os fijáis en esta cosa aquí, se ve también que LinkedList, además de implementar list, implementa también deck, que implementa queue, ¿vale?
00:16:48
Entonces, estoy implementando también esta interfaz de aquí, entonces LinkedList me puede funcionar de lista, de cola, de cola doblamente enlazada y de pila.
00:17:04
más versátil y finalmente arrelist es mejor para almacenar y acceder a datos
00:17:17
linked list es mejor para manipular datos dudas vale otro tema interfaz q vale la
00:17:32
interfaz q es una interfaz que ordena solamente de manera fifo vale es la idea
00:17:43
de que en vez de poner una lista y luego hago como le da gana pues la lista tiene
00:17:47
que mantener esta cosa de que el primero
00:17:51
que inserto será el primero
00:17:53
que pillo
00:17:55
o sea siempre extraigo
00:17:56
el
00:17:59
elemento más viejo
00:17:59
de mi lista, y por qué quiero esto
00:18:02
no lo sé, a lo mejor no lo quiero
00:18:05
si no lo quiero uso una list
00:18:07
pero si quisiera utilizar
00:18:08
este mecanismo pues
00:18:11
lo que busco
00:18:13
es una queue o una deck
00:18:15
tened en cuenta que la deck
00:18:16
es doblemente enlazada, puedo
00:18:19
enceder de un lado para el otro pero si yo sólo uso uno de los dos extremos o
00:18:20
estoy haciendo una cola normal corriente. En fin, por el primer elemento se elimina
00:18:25
primero y el último elemento se elimina por último. Vale, los elementos se añaden al
00:18:30
final de la cola, puede contener elementos duplicados, vale, porque sigue
00:18:35
siendo más o menos como una lista. Las principales operaciones son encolar y
00:18:39
obtener siguiente, vale, encolar lo pondrá al final, si quiere obtener siguiente
00:18:44
pillará el primero de la de la cola aparte de esta interfaz también existe
00:18:49
la interfaz de deck lo que permite insertar al final para hacerlo
00:18:54
además de insertar al final puede insertar al principio vale este comando
00:19:00
se llama empujar vale push
00:19:06
por el estilo estará desde que un ejemplo que implementa que es prioritario y desde
00:19:09
deck a rey deck es una implementación de una cola con dos extremos ahora si queréis empezamos de lo
00:19:17
pone esto, doble, vamos a verla, desde aquí me voy a deck, este es deck y desde aquí me voy a
00:19:26
raid deck, esta es una implementación de deck, si os fijáis debería, veis que a añadir, que es el
00:19:46
añadir normal, pero tiene también un método especial de añade primero y añade último,
00:19:55
esto me permite utilizar la cola en un sentido o en otro
00:20:00
si yo uso solo add first
00:20:04
y get last
00:20:05
pues lo que estoy haciendo es una cola correcta
00:20:08
si yo uso solo add last y get first
00:20:13
estoy utilizando una cola al revés
00:20:17
si yo uso las dos estoy utilizando una cola
00:20:18
que puede hacer desde los dos lados
00:20:21
la idea no es para qué usa y por qué
00:20:23
no lo sé, es porque a mí de alguna forma
00:20:26
me interesa eso. Fijaos que también push y pop, o sea que posiblemente se puede utilizar como una
00:20:29
pila. Y luego está PriorityQueue. PriorityQueue es una clase que implementa queue, proporciona
00:20:39
la facilidad de usar la cola, no ordena solamente de manera fifo, literalmente, sino que lo ordena
00:20:49
de una forma de prioridad, ¿vale? O sea que
00:20:57
first in, first out, pero en sentido de prioridad. Quien tiene más prioridad
00:21:01
es el primero que será extraído, ¿vale? Y esto
00:21:05
si vosotros, por ejemplo, a nivel de programación de sistema operativo, que hay varias
00:21:08
tareas que hacer y algunas tareas pueden ser más importantes que otras, pues
00:21:13
tú puedes crearte una Priority Queue para que insertes allí las tareas que tiene que hacer
00:21:17
y cuando el procesador está libre y dice voy a sacar la tarea que voy
00:21:21
hacer va a la cola de prioridad y pilla la cola la tarea con más prioridad da igual que se haya
00:21:25
insertado antes o después pues la parte ahora el cual la cuestión es que como defino la prioridad
00:21:31
o sea los objetos tendrán que tener una prioridad vale para establecer la prioridad se usa con
00:21:39
Comparable, ¿vale? Entonces los objetos que yo uso allí dentro, ¿vale? Tendrán que implementar Comparable y yo simplemente cuando voy a insertarlo en la cola lo pondré en la posición correcta en base a lo que me dice Comparable.
00:21:45
Que no necesariamente es un orden
00:22:03
Es un orden de prioridad
00:22:05
Para este caso
00:22:07
Entonces, esto ya lo hemos hablado
00:22:08
Ya lo hemos visto
00:22:11
La interfaz comparable es una interfaz
00:22:12
Que me permite comparar dos objetos
00:22:14
Fuerza que tú uses compare to
00:22:16
De un objeto
00:22:18
Y en base a esta cosa aquí
00:22:19
Tú lo que puedes hacer es comparar
00:22:22
Devolver un positivo
00:22:25
Si el objeto actual es mayor
00:22:28
Que el objeto especificado
00:22:30
negativo si es menor, cero si son de igual importancia en un cierto sentido. Él utilizará
00:22:32
esta información para ordenar en términos de prioridad. Entonces cuando yo defino el
00:22:38
compareTo para usar un objeto dentro de un priority queue, tendré que definir su comparación
00:22:45
en términos de prioridad, cuál es más importante que otro. Tened en cuenta que esto de comparable
00:22:53
me permite comparar dos elementos, sí, pero como yo decido el criterio con que se comparan, pues lo decido yo, ¿sí?
00:23:00
Y aquí abro también otra paréntesis, que a lo mejor lo veremos en algún ejemplo más adelante.
00:23:11
Imaginaos que yo tenga un string, ¿vale? Un string se puede comparar, implementa string comparable,
00:23:18
¿Cómo puedo saber si implementa string comparable?
00:23:26
Ya, exacto
00:23:34
Me voy a pijaba
00:23:36
Me voy a pijaba
00:23:38
Voy a mirar y veo que efectivamente
00:23:48
Implementa comparable
00:23:52
Entonces por aquí está compare to
00:23:54
Vale, ok
00:23:56
¿Cómo es la definición de compare to?
00:23:57
Pues posiblemente a nivel lexicográfico
00:24:02
¿Vale? Gato es menor que perro, porque gato empieza por G y perro empieza por P.
00:24:05
¿Sí? Vale.
00:24:14
¿Y qué pasa si ahora yo quiero hacer una priority queue, le quiero poner string,
00:24:16
pero la prioridad
00:24:23
de lo que representa
00:24:26
este string
00:24:28
no tiene que ser ordenada por
00:24:29
¿cómo se dice?
00:24:32
alfabéticamente
00:24:38
pero con un orden distinto
00:24:39
entonces debería crear una nueva clase
00:24:41
string no la puede usar
00:24:48
string tiene su comparación
00:24:53
¿cómo sobreescribo string?
00:24:54
¿me pongo dentro del jdk, busco string
00:24:56
y cambio el código? no
00:24:59
no se toca el jdk
00:25:00
Podría heredar string con mi string
00:25:02
Y cambiarlo
00:25:05
Pero, ¿y si tengo que usar las dos cosas?
00:25:06
O sea, que en parte
00:25:09
Cuando lo escribo al usuario
00:25:10
Quiero que se lo escriba ordenado literalmente
00:25:13
Entonces necesito el Compertur
00:25:15
Léxico gráfico
00:25:17
Pero cuando lo usa la Priority Queue
00:25:18
Quiero que lo ordene según
00:25:20
Otra cosa, por ejemplo, el numerito
00:25:22
Que le pondría al final
00:25:24
Tiene que pillar ese número y ordenarlo según ese número
00:25:25
¿Cómo lo hago?
00:25:28
Pues existe una cosa que se llama comparator.
00:25:30
El comparator es una forma de, sustancialmente, crear un objeto y darle una forma distinta de comparar las cosas.
00:25:40
En vez de crear compara y tú, usa este compare que pilla dos objetos.
00:25:53
Entonces, yo lo que puedo hacer es definir una nueva versión del compare y luego utilizarla y mantener el orden natural, o sea, el orden natural de las strings será lo que conocemos todos, el lexico gráfico, pero en casos concretos le voy a añadir un comparator nuevo,
00:25:58
que lo que permite es, oye, mira, pero ahora
00:26:19
no lo uses con
00:26:22
la comparación
00:26:24
normal, más úsala con
00:26:27
esta cosa aquí, ¿vale?
00:26:28
Un poquito más complejo que esto
00:26:30
uno de estos días hacemos una prueba
00:26:32
y vemos como
00:26:34
como sale
00:26:35
¿vale? Por ahora centrámonos en cosas
00:26:38
más útiles. Yo quería
00:26:40
ahora ir a ver
00:26:42
de Q
00:26:44
RQ
00:26:45
de queue
00:26:49
puedo ir a ver
00:26:53
priority queue
00:26:55
y priority queue
00:26:57
lo veis aquí
00:27:00
es que no puedo hacer zoom
00:27:03
lo veis
00:27:07
aquí
00:27:09
o sea una priority queue normal
00:27:11
te hará una colección
00:27:16
con luego uso string
00:27:18
pues usaré
00:27:20
compararé entre ellos los string
00:27:21
para saber como organizar la prioridad
00:27:24
Pero yo puedo crear una Priority Queue y pasarle un Comparator.
00:27:26
Entonces le estoy diciendo, mira, Priority Queue, te voy a pasar a String.
00:27:31
Pero cuidado, cuando las vas a comparar para saber la prioridad, no uses el CompareTo.
00:27:36
Pero usas el método que yo te he definido dentro de la interfaz comparator, que es este método de aquí, que es un orden distinto al orden natural que tienen estos objetos.
00:27:43
Aquí, porque aquí tú le pondrías a string1 y string2 y devolvería 0, 1 o menos 1 en base a cuál de las dos es mayor, si esta o esta otra.
00:28:07
aquí
00:28:18
tú te creas un comparator
00:28:24
que pillará string o1
00:28:27
string o2 y dirás
00:28:29
que esta string, cuando pillas
00:28:31
el numerito al final que hemos dicho antes
00:28:34
y los comparas y ves cuál es mayor o menor
00:28:35
vale, cuando luego crearás
00:28:38
tú priority queue
00:28:39
le pasas este comparator que tú
00:28:41
has creado y entonces él dirá
00:28:43
ah, vale, muy bien, no voy a utilizar
00:28:45
la lexicográfica, me voy a utilizar este
00:28:47
metodito que me has dado, para que
00:28:49
sepáis que existe, luego un
00:28:53
día de estos hacemos un ejemplo un poquito más serio pero vale el proyecto posiblemente nosotros
00:28:55
la parte de que la usaremos pocos son nada vale es para introducir el compañero bol que pero ya
00:29:04
nosotros hemos visto anteriormente por lo tanto está aquí vale pasamos a set vale y nos quedan
00:29:10
pocas transparencias vale estamos en la 23 al 29 acabamos entonces hasta ahora nosotros hemos
00:29:20
trabajado con listas sostancialmente lineales una tras de otro vale cuando entro en el set cambian un
00:29:28
poquito las cartas en tabla en la mesa hasta ahora nosotros nos importaba el orden vale o sea que
00:29:35
puede que el orden sea con prioridad puede que el orden sea invertido puede que el orden sea de
00:29:45
inserción puede ser que el orden pero el orden con que yo meto los elementos se tiene que mantener
00:29:50
si yo he puesto un objeto en segunda
00:29:56
posición, cuando voy a iterar
00:29:58
me lo quiero encontrar en segunda
00:30:00
posición
00:30:02
sin embargo en el set
00:30:03
no, en el set lo que hago
00:30:06
es, mira, voy a
00:30:08
ceder dos cosas
00:30:10
a cambio de que
00:30:12
otras
00:30:14
métodos
00:30:15
otras actividades que puedo hacer
00:30:18
sobre el set, sean
00:30:20
más fáciles, más eficientes
00:30:21
las dos cosas que cedan son que no quiero que los elementos se pueden duplicar y que no quiero
00:30:24
mantener el orden si tú quieres para ser más eficiente mezclar el orden y poner los objetos
00:30:31
como te da la gana ti organizarlos como te da la gana ti para que sean más eficientes hazlo
00:30:37
enorme a mí me interesaba el orden pues no uses un set
00:30:43
la interfaz se definió colección que no puede contener elementos duplicados en automático si
00:30:48
yo inserto un elemento que ya que no está pues él tendrá que hacer algo o sobreescribir el que
00:30:55
ya estaba o no insertarlo vale esto dependerá de la implementación que yo tengo sí y tendré
00:31:01
que leerme la presentación que uso que hace cuando añado un elemento que ya existe esta
00:31:07
interfaz contiene únicamente los métodos heredados de collection añadiendo la restricción de que los
00:31:14
elementos duplicados están prohibidos es decir si yo me busco set estos son los
00:31:20
mismos métodos que tenía en collection vale pero si me leo la descripción vale
00:31:36
me debería decir por ejemplo añade el elemento especificado en este set si no
00:31:42
está ya presente vale ha cambiado la definición si yo me
00:31:51
voy a mirar en collection lo que dice la definición del add es
00:31:56
añade este elemento a la colección y si está duplicado pues lo añade, el set
00:32:06
me añade explícitamente que no se puede duplicar, está bien el equals, ahora esto
00:32:14
quiere decir que el set en automático me lo hace, no, esta es una interfaz que era
00:32:28
interfaz era un contrato no era oye mira yo te voy a decir que tienes que hacer y aquí te lo
00:32:33
estoy explicando vale ahora que tú dices yo implementó un set y luego esto no lo hago y
00:32:48
me hago un set donde se puede poner duplicados pues allá tú lo has hecho y él no se va a dar
00:32:59
cuenta porque la semántica no la va a entender
00:33:06
pero tú te has hecho un error
00:33:08
porque no estás cumpliendo
00:33:10
con lo que tiene que hacer add
00:33:12
tú has creado tu set, mi set
00:33:14
cuando la gente
00:33:16
usará mi set, que hereda
00:33:18
de set, se esperará
00:33:20
esto
00:33:22
si tú lo has implementado de otra forma
00:33:23
que en vez de añadir el elemento
00:33:26
lo que hace, te escribe, me gustan
00:33:28
los gatitos, pues no está funcionando
00:33:30
tal y como te han pedido
00:33:33
que funcione, entonces el error es tuyo
00:33:34
Lo puedes hacer, sí, como puedes hacer todos los programas malos que quieres, ¿sí?
00:33:36
Pero la idea es que cuando tú vas a implementar set, te tienes que ceñir a lo que te pide en cada uno de sus métodos, ¿sí?
00:33:43
¿Se entiende?
00:33:57
Entonces, yo me espero también que cualquiera de estas, no un implementing de clases, cualquiera de estas clases, funcione así.
00:33:58
¿Me explico lo que quiero decir?
00:34:09
Si yo uso un triset, me espero que el triset no admita dos elementos iguales.
00:34:11
Luego me puedo ir a mirar en el triset qué hace literalmente, porque podría pasar dos cosas.
00:34:18
si yo he metido el alumno 1
00:34:24
y ahora vuelvo a poner el alumno 1
00:34:26
hay dos opciones
00:34:28
o lo que se ha insertado
00:34:30
no se inserta
00:34:32
o tiro el que estaba antes
00:34:33
y añado el nuevo
00:34:36
eso dependerá de cómo lo has implementado
00:34:37
y en la implementación
00:34:40
te lo debería decir
00:34:42
add
00:34:43
add the present
00:34:49
vamos a leer si nos explica un poquito más
00:34:50
more form
00:34:54
Si el set lo contiene ya, esta cosa de aquí no cambiará el set y devolverá false, porque te permite poner.
00:34:56
Entonces ya sé que el triset, si yo añado algo que ya existe, no cambia lo que tenía ya y me dice false.
00:35:16
Si me dice true es porque la he insertado
00:35:24
Lo leo y sé cómo funciona
00:35:26
¿Se entiende?
00:35:28
Vale
00:35:31
Más, es importante destacar que
00:35:31
Para comprobar si los elementos son duplicados o no
00:35:34
Es necesario que dichos elementos
00:35:36
Tengan implementadas de forma correcta
00:35:38
Equals y hashCode
00:35:40
¿Vale? En particular equals
00:35:42
¿Sí?
00:35:44
¿Por qué? Porque yo tengo que saber
00:35:46
Si inserto el elemento 1
00:35:48
Vale, ahora inserto el elemento 1 otra vez
00:35:50
tengo que comparar estos dos elementos
00:35:52
para saber que son iguales
00:35:54
si yo no hago nada
00:35:56
la igualdad será la que hemos dicho
00:35:57
ya muchas veces, está basada sobre
00:36:00
el concepto que sea en la misma instancia
00:36:02
que sea en la misma dirección
00:36:04
de memoria, solo en ese caso
00:36:06
son iguales
00:36:08
pero a veces eso no es suficiente
00:36:09
a veces yo tengo que añadir
00:36:12
alumnos y no tengo
00:36:14
el objeto alumnos anterior
00:36:16
estoy añadiendo un alumno que ya tiene el DNI
00:36:18
metido y ya está otro alumno
00:36:20
con el mismo DNI, pues me debería decir
00:36:22
oye, mira, no lo puedo añadir
00:36:24
¿vale? y entonces
00:36:25
el equals tendré que
00:36:27
modificarlo para que
00:36:29
haya una
00:36:31
comparación entre los DNI
00:36:33
de los alumnos y me dé
00:36:36
true si el DNI es el mismo, false si el DNI
00:36:37
son distintos, ¿vale?
00:36:40
si toco equals
00:36:41
tengo que tocar también hashCode
00:36:43
porque hashCode van juntos
00:36:45
¿vale?
00:36:48
¿qué es una función hash?
00:36:49
Ahora hablamos de eso. Para comprobar si dos sets son iguales, son el mismo set, lo que se hace es, se va elemento por elemento y se comprueba, o sea, se mira si está en el otro set.
00:36:51
Si están todos los elementos allí y son grandes iguales, los sets son iguales. O sea, que la equals entre dos sets está pensada así.
00:37:07
¿Y cuál es el H-code? Ambos métodos son importantes cuando necesitamos buscar nuestros objetos en colecciones, como el método equals, o en mapas, como el método hash.
00:37:17
Los mapas los veremos el lunes y los hash-codes principalmente se usan en mapas, aun si ahora veremos el hash-set, que lo usa también el set.
00:37:31
Como sabemos que es un mapa, lo veremos el lunes.
00:37:42
Cuando se realiza una implementación de ambos métodos
00:37:45
Si dos objetos son iguales según el método equals
00:37:49
Se debe cumplir que el resultado del método hashCode
00:37:52
También tiene que ser el mismo
00:37:55
Pero no al revés
00:37:58
O sea, dos objetos iguales
00:37:59
Tienen que dar el mismo hashCode
00:38:02
Pero dos objetos que dan el mismo hashCode
00:38:04
No necesariamente son iguales
00:38:08
¿Qué era una función hash?
00:38:11
Una función hash, o hash, o como sea, es una función que pilla objetos, ¿vale?, o en general números infinitos, ¿vale?, y una vez hecha esta función, devuelve un número más pequeño y finito de valores.
00:38:15
O sea, y aquí tengo infinitos valores, aquí tengo n valores, ¿sí?
00:38:39
Sustancialmente hace un mapeado, por eso luego se usan los maps,
00:38:47
de números infinitos, valores infinitos, posibilidades infinitas,
00:38:51
en un cierto número n de categorías, ¿sí?
00:38:57
Estas categorías son como bolsas, ¿vale?
00:39:00
Es como si yo tuviera un cajón, que son todos los números, y pero dentro de este cajón divido el cajón en secciones para que luego ordene estas cosas aquí dentro y cuando luego voy a buscar, no tengo que buscar en todo el cajón, más solo en la sección correcta.
00:39:07
¿Se entiende lo que quiero decir?
00:39:29
Asumiendo que tú tienes infinitos lápices y los categorizas por color, sí.
00:39:38
Y luego cuando buscas un color rojo, pues no tienes que ir a buscar entre la maraña de lápices,
00:39:43
más vas solo a la caja de los rojos, a la sección de los rojos.
00:39:51
¿Sí?
00:39:56
Un ejemplo fácil de entender.
00:39:58
Me creo un conjunto de categorías que son las letras
00:40:02
Entonces tengo A, tengo B, tengo C, tengo D, etcétera, etcétera, todas las letras
00:40:09
Al final tengo Z y luego tengo una categoría asterisco que es todo lo que nos caiga aquí
00:40:20
vale tendré un cierto número de letras no sé cuántas letras hay 26 pues 27
00:40:30
categorías 26 letras más una categoría comodín
00:40:37
ahora yo aquí tengo todas las string del mundo cuántas string hay
00:40:43
infinitas vale entonces si yo pillo la cadena gato la paso por esta máquina de
00:40:49
aquí que es mi funcionar y él me dice gato va en la categoría g y entonces
00:41:02
desde aquí empiezo por ejemplo una lista donde pongo gato ahora viene el usuario
00:41:14
me dice ponme otra palabra ponme la palabra árbol o no sin acento el perro
00:41:24
perro se pasa por aquí él va a la categoría p y pone aquí perro se entiende
00:41:33
¿Cómo funciona? Más o menos.
00:41:48
Ahora, yo si pongo una palabra que es gusano, esto cuando va en la H, pasará por la G.
00:41:53
Y por lo tanto, se pondrá aquí.
00:42:06
Ahora, gato y gusano son iguales.
00:42:15
¿El hashcode de gato y el hashcode de gusano son iguales?
00:42:19
Sí.
00:42:24
Porque mi funcionage es, pilla la primera letra, en base a la primera letra, ponla en la categoría.
00:42:31
Ese es mi funcionage, el funcionage que yo he definido.
00:42:40
Es una buena funcionage, no nos metemos ahí.
00:42:43
Pero la funcionalidad, la funcionage que yo hago es, pilla la string, mira la primera letra,
00:42:48
en base a la primera letra, lo pones aquí.
00:42:56
Aquí, ¿vale?
00:42:59
Ahora, pongamos que yo ponga otras mil palabras, ¿sí?
00:43:00
Y todas estas mil palabras no tienen la G como primera, ¿vale?
00:43:05
Entonces, aquí pondré varias, aquí pondré varias, aquí pondré varias,
00:43:12
aquí relleno esto, alguna no tiene nada, aquí mogollón.
00:43:16
Ahora tengo mil palabras metidas en mis ojos.
00:43:21
Si ahora busco gato, ¿cuántas comprobaciones tengo que hacer?
00:43:23
Como máximo dos.
00:43:29
O sea, porque si yo estoy buscando gato, hago primero un hash code, me voy a esta G,
00:43:34
y ahora tengo que comprobar si existe gato aquí dentro.
00:43:40
Todas las otras palabras que están en otras categorías no me interesan, seguramente no son.
00:43:45
Entonces el hashcode y el equals se usan juntos para mejorar mucho la búsqueda de este tipo
00:43:50
Yo tengo una colección de un millón de palabras
00:44:02
Pero pon que solo 10.000 son gato, son con g
00:44:10
Por lo tanto cuando voy a buscar una palabra que empieza por g
00:44:15
Para saber si la tengo o no en mi diccionario
00:44:19
Pues no la tengo que buscar sobre un millón de palabras
00:44:21
La busco sobre las 10.000 que empiezan por G.
00:44:24
Tú puedes hacer todos los niveles que quieras, pero un objeto tiene un hash code.
00:44:35
Ahora, tú puedes decir, no, mira, en vez de tener 26 categorías, tengo 1.000 categorías,
00:44:41
basadas sobre las primeras dos letras.
00:44:48
Entonces, gato y gusano no caen en la misma cosa.
00:44:51
Entonces, la clave de la función hash.
00:44:58
Funcionage es buena cuando distribuye bien en sus categorías los elementos.
00:45:02
Si todos los elementos tienden a caer en la misma categoría, la Funcionage es fea.
00:45:10
Pero siempre tiene que valer el hecho que si yo busco gato y tengo la cadena gato,
00:45:18
esta cosa de aquí, asumiendo que sea un objeto distinto de este de aquí,
00:45:27
porque son dos strings creadas distintamente
00:45:32
dos objetos distintos
00:45:34
pues me tienen que dar el mismo hashCode
00:45:35
en este caso me tienen que dar G
00:45:37
me tienen que dar esta categoría aquí
00:45:39
si esto no vale
00:45:41
pues cuando yo lo buscaré
00:45:43
no lo estaré buscando en el sitio correcto
00:45:45
entonces el equals no me servirá
00:45:48
por esta razón
00:45:50
dos
00:45:51
si yo tengo dos elementos
00:45:52
dos objetos que den
00:45:55
equals igual
00:45:56
también su hashCode tiene que ser igual
00:45:59
Si su hashCode es igual, no necesariamente son el mismo objeto. Estarán en la misma categoría, pero no necesariamente son iguales. ¿Queda claro?
00:46:01
Ahora, esto con string es para que lo entendamos nosotros
00:46:14
En la realidad, yo aquí no tengo string
00:46:19
Yo aquí tengo objetos
00:46:22
Por ejemplo, tengo alumnos
00:46:26
Y tengo una función hash que transforma los alumnos en números
00:46:29
La función hash, el hash code, si miráis, devuelve un int
00:46:39
Entonces, si aquí tengo el alumno Estefano con edad 43, con dirección no sé cuánto, no os la digo, con cosas por el estilo, ¿vale?
00:46:44
Y ahora tengo que hacer esto, lo paso por aquí, lo paso en esta máquina mágica y esto vale 3.
00:46:57
Perfecto, este alumno de aquí, que es el alumno A, lo pondré en la categoría 3.
00:47:07
Ahora, ¿cómo he sacado este 3 a partir de mi dirección en mi nombre?
00:47:13
Que no lo sé
00:47:19
No lo sé
00:47:19
Lo que tengo que evitar es que
00:47:21
Ahora tengo un elemento B y también caiga en 3
00:47:26
Ahora tengo un elemento C y también caiga en 3
00:47:29
Porque cuanto más caen en la misma categoría, pues mal
00:47:31
Ahora, ¿yo sé hacer una cosa de ese estilo?
00:47:34
¿Sé hacer una buena funcionage?
00:47:44
En un sistema en el que tiene que estar optimizado, tiene que ir rápido y tiene que funcionar bien
00:47:47
Pues habrá un equipo de matemáticos que se pondrán allí y encontrarán una función hash
00:48:06
Que funcione bien para ese entorno, para organizar esos objetos
00:48:13
nosotros
00:48:17
por ejemplo, yo tengo
00:48:20
más que sé yo, ejercicio básico
00:48:22
sistema de objeto, herencia
00:48:35
en herencia algún objeto lo tengo
00:48:36
cuadrado
00:48:38
por ejemplo, tenía los empleados
00:48:43
empleados era una clase, ¿vale?
00:48:45
esta cosa de aquí, ahora, a partir de aquí
00:48:50
¿cómo saco
00:48:53
una función hash?
00:48:55
por ejemplo, podría pillar
00:48:57
la string y usar
00:48:58
la hash de string
00:49:00
entonces
00:49:01
podría decir yo
00:49:04
que oye mira
00:49:08
no lo sé
00:49:09
porque yo no sé
00:49:11
cómo funciona
00:49:12
la hash de string
00:49:12
pero me fío
00:49:14
que quien ha hecho
00:49:15
string
00:49:16
haya hecho un buen trabajo
00:49:16
entonces digo
00:49:17
voy a utilizar
00:49:18
lo mismo de string
00:49:19
vale
00:49:20
cuidado
00:49:21
vale
00:49:22
porque esto tiene
00:49:23
implicaciones
00:49:24
debería pensar
00:49:25
si más
00:49:25
pero más
00:49:26
si tengo dos
00:49:26
con el mismo nombre
00:49:27
pero salario distinto
00:49:28
¿eh?
00:49:29
¿qué pasaría?
00:49:29
pues entonces
00:49:32
para obviarnos
00:49:32
a estos problemas
00:49:34
que son problemas
00:49:35
más
00:49:35
abstractos y cosas por el estilo
00:49:36
mi amigo personal
00:49:38
el
00:49:41
Eclipse nos da
00:49:41
generate as code and equals
00:49:45
tú pinchas aquí
00:49:47
seleccionas aquí
00:49:49
que quieres que conte
00:49:51
para el
00:49:53
equals, vale
00:49:54
a mí por ejemplo, yo quiero
00:49:56
fecha era fecha de nacimiento
00:49:59
el salario no me interesa
00:50:00
para comparar dos
00:50:03
Para saber si dos empleados son el mismo empleado, me interesa saber el nombre del empleado y la fecha en la que se ha llegado a trabajar.
00:50:04
Si estas dos son iguales, pues nunca contrataré dos personas que se llamen iguales el mismo día.
00:50:15
No lo hago por decisión personal.
00:50:26
Entonces, elijo que fecha y nombre sean los que se han...
00:50:29
Mirad que aquí dice, selecciona los campos para incluir en el hash code y en el equals.
00:50:32
Le doy a Generate y él me ha hecho un equals.
00:50:38
Vale, perfecto, con la cosa así.
00:50:43
Fijaos que mira que si son exactamente la misma instancia es true.
00:50:45
Si object es null, pues entonces no son iguales.
00:50:51
Comprueba que sean de la misma clase.
00:50:54
Si son de la misma clase, pues entonces comprueba campo por campo la fecha y el nombre.
00:50:56
vale, perfecto, esto funciona
00:51:02
y también me hace esta cosa aquí
00:51:06
¿y qué es esto? no lo sé
00:51:09
no lo quiero saber
00:51:15
es una función hash que me da él
00:51:17
basada sobre este valor y este valor
00:51:20
él lo pilla, lo machaca, hace cosas raras
00:51:23
un poco de mojo, jumbo
00:51:27
no sé qué, y me devuelve un entero
00:51:30
Y es él que me garantiza que si dos son iguales, pues este número será igual.
00:51:33
Ahora, lo que yo sí tengo que saber es cuándo tengo que hacer un override de esto.
00:51:46
Y sobre todo, no hacer esto.
00:51:52
Esto es un suspenso en mi examen.
00:51:55
Si estás tocando equals, pero no has tocado el hash code, es un suspenso en mi examen.
00:51:58
Porque ahora estarías usando el equals de esta clase con el hashcode de object.
00:52:07
Y entonces es posible que, como el equals de aquí me puede dar, o sea, el equals y el hashcode de object van juntos sobre la base de que sean la misma instancia,
00:52:15
ahora me lo estás usando con otro criterio de igualdad, y es posible que a veces cosas que sean iguales no den el mismo hashcode.
00:52:25
Y eso no puede ser.
00:52:31
si ahora si tú no lo usas en un asset por ejemplo pues esto no se usa entonces
00:52:32
no te daría problemas ahora otra cosa es que luego llega uno tú has hecho alumno
00:52:47
lo has puesto así has hecho empleado las puestas y un día llega él y usa tu
00:52:52
empleado en un asset y le colapsa el programa porque tú lo has hecho mal
00:52:57
Porque tú deberías haber hecho esto
00:53:02
¿Se entiende?
00:53:04
Ok, luego vosotros
00:53:08
Buscáis más información
00:53:09
Vais más en profundidad
00:53:11
Entendéis bien qué es esto y cómo se hace
00:53:12
Y queráis hacer vuestra versión de la Shcode
00:53:15
Encantado de la vida
00:53:17
¿Sí?
00:53:19
Vale
00:53:23
Técnicamente, ¿os acordáis?
00:53:24
Hago en
00:53:29
En cuadrado
00:53:30
si acordáis
00:53:33
hay un main
00:53:35
para main
00:53:36
si hago cuadrado
00:53:38
cuadrado es igual a
00:53:44
new cuadrado
00:53:48
si no me equivoco
00:53:49
de lado 3
00:53:51
vale, si hago
00:53:53
siso cuadrado
00:53:55
y ejecuto
00:53:59
esto
00:54:02
me sale esta cosa aquí, esto que es
00:54:02
este de aquí
00:54:06
es el tipo
00:54:12
es la clase, la clase cuadrado
00:54:13
del paquete
00:54:15
R figuras, este debería
00:54:16
ser el hashcode
00:54:19
creo, si
00:54:21
pero no estoy seguro
00:54:22
y por lo tanto hacemos eso
00:54:25
cuadrado
00:54:27
punto
00:54:31
hashcode
00:54:32
deberíamos ver si esta cosa de aquí
00:54:34
en hexadecimal es esta cosa aquí
00:54:41
que no tengo ni idea
00:54:43
probablemente no
00:54:44
probablemente no, vale
00:54:46
probablemente esto es más complejo
00:54:51
que solo esta cosa aquí, pero yo tengo entendido
00:54:54
que aquí esto tiene alguna
00:54:57
referencia, vamos a ver si
00:54:58
tengo suerte, me parece
00:55:00
demasiado pequeño para ser este número aquí
00:55:02
científica, no
00:55:04
programador
00:55:08
esto
00:55:10
mira
00:55:12
6F53
00:55:14
9K, exactamente
00:55:17
es
00:55:19
el hash code
00:55:22
en esta decimal
00:55:24
pues ya está, más o menos
00:55:25
algo de hash se ha quedado
00:55:38
si, se os quede
00:55:40
aquí
00:55:43
si queréis os metéis aquí
00:55:43
este de aquí tengo la sospecha que no funcione
00:55:46
¿vale? pero este link de aquí
00:55:48
sí que funciona
00:55:51
y os explico un poquito más, y si no siempre
00:55:51
podéis indagar cuanto queráis más
00:55:54
sobre esta cosa aquí
00:55:56
la interfaz 7, nosotros
00:55:57
veremos 3 o 2
00:56:00
probablemente, clases interesantes
00:56:02
que son hset y triset
00:56:04
¿vale? hset es
00:56:06
un conjunto que usa h
00:56:08
para organizar las cosas, para una
00:56:10
tabla h parecida a lo que hemos visto ahora
00:56:12
mientras que triset
00:56:14
organiza las cosas como un árbol
00:56:16
un árbol
00:56:18
¿vale? lo hemos visto antes
00:56:20
y si os fijáis
00:56:22
está en sorted set, o sea que
00:56:24
los elementos que añade, no los
00:56:26
añade al azar, mas los añade
00:56:28
organizados
00:56:30
Hset
00:56:31
Esta implementación almacena los elementos en una tabla H
00:56:34
¿Una tabla H qué es?
00:56:38
Esto
00:56:39
Esta es una tabla H
00:56:39
¿Vale?
00:56:42
Con mis categorías
00:56:43
Taca, taca, taca, taca
00:56:44
Y cuando yo te doy un elemento
00:56:45
Pues ese elemento va en una zona
00:56:47
Este elemento aquí va en otra cosa
00:56:49
Esta es una tabla H
00:56:51
¿Sí?
00:56:52
No permite tener elementos duplicados
00:56:54
Es la implementación con mejor rendimiento
00:56:57
De todas
00:57:00
¿Vale?
00:57:01
pero no garantiza ningún orden a la hora de realizar iteraciones
00:57:01
o sea que yo he metido
00:57:05
el A y luego el B y luego el C
00:57:07
cuando itero a lo mejor antes me encuentro el B
00:57:11
luego el A y luego el C
00:57:13
no lo sé, los encontré todos
00:57:15
pero si voy a buscar el set
00:57:18
no se ha mantenido ningún tipo de orden
00:57:22
esto es importante
00:57:23
o sea que si yo no quiero el orden y no me interesan los duplicados
00:57:26
uso Hset, es lo más rápido posible. Tiene tiempo constantes en las operaciones básicas, inserción,
00:57:31
búsqueda y remoción, tiempo constante, lo que es muy bueno. Yo puedo aumentar el número n de
00:57:40
elementos y siempre tardaré una constante para llegar allí. La constante será grande,
00:57:53
10 segundos pero no aumenta mucho con el aumentar de los números n si fuera en vez el tiempo que
00:57:58
tarda en función de n o lineal con n o cuadrática en el cuadrado pues cuanto más elemento pongo más
00:58:08
será difícil es lo que pasaba con linked list ayer que yo lo hacía por mil mil elementos y
00:58:16
funcionaba rápido, 10.000 elementos
00:58:24
rápido, en cierto momento llegaba a 100.000
00:58:26
elementos y ya tardaba
00:58:28
un mogollón. Iba tardando siempre
00:58:30
más, siempre más, siempre más.
00:58:32
Si tengo suerte, es lineal.
00:58:34
Cuanto más aumento los elementos,
00:58:36
más aumenta el tiempo en una función lineal.
00:58:38
Si tengo mala suerte, es exponencial.
00:58:41
Sí. Pero
00:58:45
lo que no mantiene es
00:59:00
el orden con que tú insertas
00:59:03
las cosas. Tú insertas
00:59:05
A, B, C y D. Luego pillas el tu
00:59:07
array y no te esperes de encontrar
00:59:09
A, B, C, D dentro de este array.
00:59:11
Lo que te puedes encontrar es
00:59:15
C, D, B, A. O te puedes encontrar
00:59:16
A, B, C, D porque has tenido suerte. Pero no
00:59:19
está garantizado. Una lista, tú
00:59:21
pones A, B, C, D, lo haces
00:59:23
tu array, en el array te encuentras A, B,
00:59:25
C, D. Porque el orden es importante.
00:59:27
¿Sí?
00:59:30
O sea, puede hacer
00:59:35
un set ordenado, si, pongo dentro del objeto que guardo un numerito
00:59:36
secuencial, un serial number y luego que le mezcle lo que da la gana y cuando lo
00:59:43
saco pues se que orden tiene, lo voy a hacer, pero si a mí me interesa el orden no voy a
00:59:48
utilizar set
00:59:55
es la presentación más empleada debido a su rendimiento bla bla bla bla bla bla
00:59:59
Triset es una implementación que almacena los elementos ordenando en función de su valor.
01:00:03
Es bastante más lento que Hset en el proceso de inserción, pero el tiempo de acceso y recuperación es bastante rápido.
01:00:15
Los elementos almacenados deben implementar la interfaz comparable y te da un rendimiento de logaritmo de n,
01:00:23
O sea, con el aumentar de los elementos que pongo, cuanto tardo en pillar las cosas es logarítmica.
01:00:34
El logaritmo, si os acordáis, es una función así.
01:00:43
O sea, que cuanto más aumenta, poco aumenta el tiempo que tardo.
01:00:46
Entonces es muy bueno para grandes colecciones de datos.
01:00:52
Repaso de la matemática que seguramente sabéis.
01:00:56
Si yo tengo la complejidad, o sea, el tiempo que tarda en hacer las operaciones
01:00:59
Y el número de elementos
01:01:12
Yo puedo tener distintas funciones
01:01:15
Puedo tener una complejidad lineal
01:01:19
Esto es que cuanto más aumente n, más será complicado hacerlo
01:01:22
¿Vale? Está bien
01:01:27
Puedo tener una cuadrática
01:01:28
que cuanto más aumentan los n
01:01:34
mucho más aumentan
01:01:39
los cosas
01:01:42
si mi algoritmo funciona así
01:01:43
no me vale para números
01:01:46
grandes, cuanto más
01:01:48
elemento añado
01:01:50
mi programa peor funcionará hasta un momento
01:01:51
en que no colapsará
01:01:54
el logaritmo
01:01:55
sería una cosa así
01:01:58
y entonces no es exactamente
01:02:00
igual
01:02:07
y entonces es bueno
01:02:07
constante
01:02:10
sería así
01:02:13
no lo conseguiré nunca
01:02:21
se entiende
01:02:23
a lo mejor es más alto
01:02:25
pero esto irá creciendo, creciendo, creciendo
01:02:28
técnicamente está a 1 pero bueno
01:02:30
mientras este de aquí
01:02:32
la mejor es que sea constante
01:02:33
luego logarítmica, luego lineal
01:02:35
luego exponencial, cuadrática
01:02:38
y cosas por el estilo
01:02:40
¿sí?
01:02:40
vale
01:02:44
Pues triset trabaja sobre el logaritmo de n.
01:02:45
Bien, es más lenta en inserción con respecto a esta de aquí, a la anterior.
01:02:48
Pero una vez insertado, si esto es que yo inserto, por ejemplo, inserto a los alumnos,
01:02:56
tardará un rato insertar a los alumnos, pero luego manejarlos, buscarles, cosas por el estilo,
01:03:00
es muy rápido, pues me puede valer.
01:03:04
Repito que se tiene que, para usar una triset, los elementos que uso,
01:03:07
los objetos que uso tienen que implementar con comparable. ¿Por qué? Porque el triset funciona así.
01:03:12
Pongamos que yo tenga que poner tres objetos. El objeto A, el objeto B y el objeto C. ¿Vale?
01:03:23
¿Qué hace? Pues A lo pone aquí como raíz. Perfecto. A lo he puesto. Ahora tengo que poner B.
01:03:32
Comparo A con B
01:03:42
Si B es menor, lo pongo en este lado
01:03:44
Si B es mayor, lo pongo en este lado
01:03:47
Entonces, pongamos que B sea mayor
01:03:50
Para poder hacer la comparación entre A y B que necesito
01:03:55
El compare to
01:03:59
Entonces, necesito que los objetos este de aquí
01:04:04
Implementen compareable
01:04:08
Porque cuando voy a insertar B, tengo que hacer
01:04:10
B compare to A
01:04:13
Y si B es mayor, lo pondré aquí. Si B era menor, lo pondré aquí. Ahora me viene C. Entro aquí. Pongamos que A sea menor que C. Por lo tanto, lo tengo que poner en esta subrama de aquí.
01:04:15
C, ¿es mayor o menor que B? Menor, pues lo pongo a su izquierda. Ahora pongo D, ¿D es menor que A? Pues lo pongo aquí. Ahora pongo E, ¿E es mayor que A y mayor que B? Pues lo pongo aquí. ¿Entendéis?
01:04:30
Entonces, la idea es que esto no vaya demasiado en profundidad
01:04:54
Cuanto menos profundo es
01:05:00
Si ahora, por ejemplo, tengo que buscar C
01:05:03
Tardo 1, 2, 3 comprobaciones
01:05:06
En vez de 1, 2, 3, 4, 5 comprobaciones
01:05:10
¿Se entiende?
01:05:14
O si busco E, que es el último que he puesto
01:05:17
Si esto fuera una lista y lo buscara E
01:05:19
Debería hacer 5 comprobaciones
01:05:22
Porque he puesto A, B, C, D y ahora he encontrado
01:05:24
En vez con el árbol solo tardaría 3
01:05:28
Cuanto más este árbol crezca
01:05:31
Mejor veo la diferencia entre lista y cosas así
01:05:35
No necesariamente porque podría haber un árbol así
01:05:39
Pero estarías perdiendo uno
01:05:50
el problema es si tú
01:05:59
los pones ordenados
01:06:05
y entonces te sale un árbol así
01:06:07
pero al fin y al cabo
01:06:09
si te sale un árbol así
01:06:18
tiene la misma complejidad de
01:06:20
de una lista
01:06:22
o sea que en el caso pésimo
01:06:23
en el que mira
01:06:27
has hecho lo peor que podías hacer
01:06:29
pues es igual a una lista
01:06:30
por lo tanto
01:06:32
con que un par de veces
01:06:34
te haya hecho esto
01:06:36
y has ganado algo
01:06:38
porque sustancialmente
01:06:41
se basa sobre la cosa
01:06:46
y cuando voy a buscar
01:06:47
puedo eliminar
01:06:47
enteros subárboles
01:06:48
si yo estoy buscando
01:06:49
un elemento
01:06:52
que es menor de A
01:06:53
todo este subárbol
01:06:54
lo puedo eliminar
01:06:55
¿sí?
01:06:58
luego tú tampoco
01:07:02
o sea tú añades las cosas
01:07:03
a lo mejor te va a dar
01:07:04
al usuario
01:07:05
lo mejor
01:07:05
es que sea lo más
01:07:07
distribuido posible
01:07:08
y eso es
01:07:09
lo menos profundo posible
01:07:10
si funciona así
01:07:11
perfecto
01:07:13
también existen
01:07:14
ahora esto lo deberíamos mirar
01:07:16
pero existen cosas que te permiten
01:07:20
pillar un árbol así y reestructurarlo
01:07:22
por ejemplo diciendo ahora la raíz es esta
01:07:25
y lo reestructura todo
01:07:27
o tú lo puedes hacer, dices a un cierto momento me creo
01:07:29
hago una operación de reestructurar
01:07:33
en el que miro esta cosa de aquí, me doy cuenta que está en esta cosa de aquí
01:07:37
y digo en vez de insertarlo aquí
01:07:41
hago una
01:07:43
una iteración sobre estos, pero
01:07:44
empiezo insertando esto
01:07:47
y luego inserto esto
01:07:48
que irá aquí, y luego
01:07:51
inserto esto, que irá aquí
01:07:53
y lo vuelvo a reestructurar en un árbol
01:07:55
más bonito, a lo mejor esto lo hago una vez
01:07:57
al mes, añado datos, añado datos
01:07:59
y una vez al mes hago una operación
01:08:01
de reestructuración para que mi árbol
01:08:03
sea más eficiente, porque no
01:08:05
ahora después miramos si existe
01:08:06
dejadme un segundo que
01:08:09
quiero ver que
01:08:11
Triset
01:08:12
Y link dash set
01:08:14
No me interesa
01:08:16
Estas son las funciones que hace
01:08:17
El triset
01:08:20
Que me puede sustancialmente
01:08:22
Ir a mirar
01:08:24
Las ramas
01:08:25
Si la rama mayor o menor
01:08:28
Y con este de aquí puedo navegar
01:08:29
Sobre el triset
01:08:32
Lo miráis después
01:08:33
Y ya está
01:08:36
- Materias:
- Programación
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Primer Curso
- Autor/es:
- Stefano Chiesa
- Subido por:
- Stefano C.
- Licencia:
- Reconocimiento - No comercial
- Visualizaciones:
- 5
- Fecha:
- 4 de febrero de 2025 - 12:40
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 1h′ 08′ 38″
- Relación de aspecto:
- 16:10 El estándar usado por los portátiles de 15,4" y algunos otros, es ancho como el 16:9.
- Resolución:
- 1152x720 píxeles
- Tamaño:
- 226.85 MBytes