1 00:00:00,000 --> 00:00:06,620 Voy a grabar esta clase, por lo tanto, si habláis, me dais vuestro consentimiento para que grabe vuestra voz. 2 00:00:07,280 --> 00:00:20,559 Vale, entonces, el último, digamos, tipo de, como diría, de estructura dinámica, ¿vale? 3 00:00:20,600 --> 00:00:25,579 De almacenamiento de datos, que vamos a ver, son, por ahora, son los sets, ¿vale? 4 00:00:25,579 --> 00:00:50,119 El set es un conjunto. En inglés quiere decir conjunto. Si pensáis vosotros como está dicho un conjunto, un conjunto es una forma para almacenar datos, pero no estamos en un cierto sentido trabajando con instancias que representan una copia de un determinado objeto. 5 00:00:50,119 --> 00:01:10,920 Más bien, el concepto de ese objeto en general. Me explico. Por ejemplo, de libros. Tú tienes un libro de programación y tú puedes ver este libro desde una perspectiva de una tienda que tiene seis copias de ese libro. 6 00:01:10,920 --> 00:01:16,560 y entonces tiene que vender las seis copias y cada copia es un objeto distinto o lo puedes 7 00:01:16,560 --> 00:01:22,140 ver desde una perspectiva de una biblioteca que es si tengo seis copias pero sustancialmente tengo 8 00:01:22,140 --> 00:01:31,599 ese libro vale en como si fuera un catálogo vale entonces existe ese libro luego de ese libro se 9 00:01:31,599 --> 00:01:39,420 pueden hacer 50 mil copias pero a mí me interesa gestionar o de una editorial gestionar el concepto 10 00:01:39,420 --> 00:01:49,200 de que existe ese libro. Entonces, si estuviéramos en el ejemplo de que yo tengo varias copias, 11 00:01:49,200 --> 00:01:55,640 pues podría utilizar una list, porque añado cada copia en la lista y cada copia es distinta 12 00:01:55,640 --> 00:02:01,040 hasta si es el mismo libro, hasta si el equals diría true, pues añadiría varios objetos 13 00:02:01,040 --> 00:02:08,020 dentro de la lista. Sin embargo, si yo quiero considerarlo como un editorial, entonces una 14 00:02:08,020 --> 00:02:12,699 vez que ha añadido este libro pues no quiero volver a añadirlo porque ya está este libro 15 00:02:12,699 --> 00:02:19,259 pues entonces usaría un set vale la cosa fundamental del set de la diferencia con 16 00:02:19,259 --> 00:02:25,840 respecto a la lista es que no puede contener elementos duplicados eso es lo que tengo que 17 00:02:25,840 --> 00:02:35,259 tener en mente yo cuando me acerco a estoy haciendo el diseño de mi programa de mi sistema 18 00:02:35,259 --> 00:02:38,819 y tengo que decidir, ¿qué hago? ¿Uso una lista o uso un set? 19 00:02:39,340 --> 00:02:46,000 La decisión allí es, ¿quiero que los elementos que estoy guardando puedan ser duplicados o no? 20 00:02:46,539 --> 00:02:53,159 Si quiero que no se puedan duplicar, pues entonces el set probablemente es donde quiero ir. 21 00:02:53,439 --> 00:02:59,819 La otra cuestión que tengo que tener en cuenta es si quiero mantener un orden o no de inserción. 22 00:02:59,819 --> 00:03:03,259 las listas mantienen el orden de inserción 23 00:03:03,259 --> 00:03:05,460 como siempre añaden al final con la alt 24 00:03:05,460 --> 00:03:08,960 pues el último añadido estará al fondo de la lista 25 00:03:08,960 --> 00:03:11,439 sin embargo en el set no 26 00:03:11,439 --> 00:03:14,759 el set guarda las cosas allí dentro 27 00:03:14,759 --> 00:03:16,580 como mejor le viene 28 00:03:16,580 --> 00:03:18,919 para que sea más eficiente 29 00:03:18,919 --> 00:03:23,520 y más rápido luego en poder buscar 30 00:03:23,520 --> 00:03:25,419 o poder sacar el elemento 31 00:03:25,419 --> 00:03:28,699 entonces mientras en una lista 32 00:03:28,699 --> 00:03:34,460 si yo pongo el elemento a elemento b elemento c cuando luego lo voy a leer la lista me encontraré 33 00:03:34,460 --> 00:03:42,419 a b y c en un set no en un set pongo a b y c y puede ser que cuando vaya a leerlo cuando vaya 34 00:03:42,419 --> 00:03:51,379 a iterar sobre él o con un iterator pues que existe porque set deriva de collection que 35 00:03:51,379 --> 00:03:56,719 deriva de iterable por lo tanto aquí también puede hacer un iterator exactamente como antes 36 00:03:56,719 --> 00:04:05,180 vale, pero en vez de ir en el orden de inserción, pues será en el orden que prefiere el mismo set. 37 00:04:06,080 --> 00:04:12,449 Dudas hasta aquí. La interfaz contiene únicamente los métodos del dado de collection, 38 00:04:12,449 --> 00:04:17,370 añadiendo restricciones que los elementos duplicados están prohibidos. Porque si yo me 39 00:04:17,370 --> 00:04:25,629 voy a mirar collection tiene estos métodos de aquí, vale, estos son los métodos que todas 40 00:04:25,629 --> 00:04:31,449 las colecciones tienen que tener pues me voy a mirar set son los mismos métodos pero se añade 41 00:04:32,629 --> 00:04:39,689 si no está ya vale o sea cuando ya añado algo cuando intento insertar un nuevo elemento sólo 42 00:04:39,689 --> 00:04:49,209 lo inserto si no está anteriormente si éste ya está presente ahora como sé si un objeto está 43 00:04:49,209 --> 00:05:02,430 presente está presente si el concepto está si en la lista yo añado el elemento a vale perfecto añade 44 00:05:02,430 --> 00:05:07,230 otra vez el elemento a pues se me añade ningún problema porque puede ser puede haber elementos 45 00:05:07,230 --> 00:05:17,230 duplicados en el séptimo dicho que no como detectó si un elemento es duplicado como comparó con otro 46 00:05:17,230 --> 00:05:31,990 Entonces allí yo tengo que tomar una decisión, tengo que definir cuál es el concepto de 47 00:05:31,990 --> 00:05:40,870 igualdad entre dos de mis objetos. El concepto de igualdad más básico es el que da object y ya 48 00:05:40,870 --> 00:05:45,970 implementa object. Object tiene el método equals y dentro está implementado como dos objetos son 49 00:05:45,970 --> 00:05:51,790 iguales si son el mismo jefe. Yo tengo dos referencias. Estas dos referencias 50 00:05:51,790 --> 00:05:57,670 apuntan a la misma instancia, pues son iguales. Si no, no. Esa es la forma más 51 00:05:57,670 --> 00:06:02,589 básica de decir que dos objetos son iguales. 52 00:06:02,589 --> 00:06:06,970 Pero no siempre es la que quiero yo. Por ejemplo, en el caso del libro, 53 00:06:06,970 --> 00:06:13,449 que decíamos antes de la editorial, pues no es tanto la instancia que me interesa 54 00:06:13,449 --> 00:06:20,889 cuanto las características del libro. Yo podría crearme un libro que sea programación de Java de 55 00:06:20,889 --> 00:06:29,290 una cierta editorial y luego crear otro objeto que sea programación de Java de esa misma editorial y 56 00:06:29,290 --> 00:06:34,670 me gustaría que cuando comparo estos dos objetos, no obstante sean objetos distintos, sean instancias 57 00:06:34,670 --> 00:06:39,250 distintas porque los he creado en momentos distintos, pues la respuesta de estos son el 58 00:06:39,250 --> 00:06:48,069 mismo libro fuera así. Tengo que definir cuando dos objetos que he creado yo son iguales. Para 59 00:06:48,069 --> 00:06:54,910 eso tengo que implementar el método equals. En el método equals vosotros estáis definiendo cuando 60 00:06:54,910 --> 00:07:02,790 dos de los objetos que habéis creado vosotros se consideran iguales y cuando no. Y esto implicará 61 00:07:02,790 --> 00:07:13,889 directamente si se puede insertar en un set o no. Si yo he definido que dos gatos son iguales cuando 62 00:07:13,889 --> 00:07:20,029 pesan igual, pues si pongo dos gatos completamente distintos, de color distinto, con el 63 00:07:20,029 --> 00:07:27,670 mismo peso en el set, me dirá no lo puedo insertar porque ya existe este gato. Porque para mí los 64 00:07:27,670 --> 00:07:39,850 gatos son solos". Entonces, ¿qué hago? Si eso no me vale, modificaré la definición de igualdad 65 00:07:39,850 --> 00:07:46,069 entre gatos. Si me doy cuenta, es siempre el mismo discurso que hacíamos antes a nivel de diseño. 66 00:07:46,069 --> 00:07:54,310 Cuando yo creo mi clase alumno, mi clase profesor, mi clase coche o lo que sea, pues tengo que pensar 67 00:07:54,310 --> 00:08:00,490 a nivel de este programa cuando dos profesores son el mismo profesor, cuando dos alumnos son 68 00:08:00,490 --> 00:08:06,790 el mismo alumno, cuando dos coaches son el mismo coach. Y lo defino yo. Soy yo el designer, 69 00:08:06,790 --> 00:08:11,829 en vuestro caso es que haréis estos ejercicios, y vosotros que definís cuando dos objetos son iguales. 70 00:08:11,829 --> 00:08:17,529 Normalmente una persona, cuando el DNI es el mismo. Uno puede decir cuándo son los nombres 71 00:08:17,529 --> 00:08:23,230 y apellidos distintos, iguales, pero a lo mejor hay dos personas que se llaman exactamente iguales, 72 00:08:23,230 --> 00:08:31,370 son dos personas distintas. Eso lo tenéis que definir vosotros, repito, siempre en el marco del problema. 73 00:08:31,370 --> 00:08:37,850 Por ejemplo, en nuestra escuela, el ejemplo que hacemos de escuela, pues podríamos utilizar un set, ¿vale? 74 00:08:38,009 --> 00:08:44,970 Porque los alumnos que entran en la escuela son únicos. Entonces no quiero que se repita el mismo alumno. 75 00:08:45,250 --> 00:08:51,769 Una vez que está en la escuela ya está dentro. Solo que tengo que definir una forma para identificar 76 00:08:51,769 --> 00:08:53,850 dos alumnos que son el mismo alumno 77 00:08:53,850 --> 00:08:55,929 y dos alumnos que son alumnos 78 00:08:55,929 --> 00:08:57,990 distintos, pero con el mismo nombre, apellido, etc. 79 00:08:58,350 --> 00:08:59,629 Como por ejemplo con el NIA, 80 00:08:59,750 --> 00:09:02,070 el número de identificación de alumno, o con el DNI, 81 00:09:02,210 --> 00:09:03,629 o con lo que queramos. 82 00:09:04,730 --> 00:09:06,070 ¿Sí? Un conjunto 83 00:09:06,070 --> 00:09:07,970 de estos. O sea, no es que necesariamente 84 00:09:07,970 --> 00:09:09,769 tienes que pillar un atributo y valorarlo 85 00:09:09,769 --> 00:09:11,809 sobre el atributo. Pueden ser un conjunto de 86 00:09:11,809 --> 00:09:14,029 atributos que sean iguales. 87 00:09:14,110 --> 00:09:14,190 ¿Sí? 88 00:09:15,830 --> 00:09:21,809 Dudas hasta aquí. ¿Qué más? 89 00:09:22,190 --> 00:09:23,789 Es importante destacar 90 00:09:23,789 --> 00:09:29,830 para comprobar si los elementos son elementos duplicados o no lo son, es necesario que dichos 91 00:09:29,830 --> 00:09:35,610 elementos tengan implementada de forma correcta los métodos Equals y Aschcode, ¿vale? 92 00:09:35,610 --> 00:09:54,250 Tened en cuenta que Equals y Aschcode los encontramos en Objects, Aschcode e Equals, 93 00:09:54,250 --> 00:10:01,629 lo que quiere decir que cualquier objeto que vosotros creáis tiene Equals y tiene Aschcode. 94 00:10:02,809 --> 00:10:11,590 Los tiene, ya, ¿vale? Pero de una forma muy básica, de una forma muy elemental, que muchas veces hay que modificar, ¿sí? 95 00:10:16,600 --> 00:10:25,539 Para comprobar si los sets son iguales, se comprobarán si todos los elementos que los componen son iguales, sin importar el orden en que ocupan dichos elementos, ¿vale? 96 00:10:25,539 --> 00:10:30,399 Mientras que una lista, a lo mejor, con los mismos elementos, pero en orden distinto, 97 00:10:30,480 --> 00:10:35,340 podrías decir que son dos listas distintas, dos sets, cuando los compruebas, 98 00:10:35,460 --> 00:10:41,720 compruebas que todos los elementos de uno compaían en el otro, aparezcan en el otro, ¿vale? 99 00:10:42,159 --> 00:10:46,100 No tanto el orden. El orden en los sets no tiene que ver, ¿vale? 100 00:10:47,059 --> 00:10:51,899 Algunos sets sí, pero no el orden de inserción. Eso es importante. 101 00:10:51,899 --> 00:11:01,769 EqualsHashCode, ¿vale? Ambos métodos son importantes para cuando necesito buscar objetos en colecciones, ¿vale? 102 00:11:01,830 --> 00:11:07,350 Sobre todo el método de EqualsHashCode en colecciones, el HashCode es muy útil en los mapas, ¿vale? 103 00:11:08,009 --> 00:11:16,269 Pero nosotros también veremos el HashSet que sí que usa el HashCode, ¿vale? Ahora hablaremos de eso. 104 00:11:17,570 --> 00:11:23,370 Cuando se realiza una implementación de estos métodos, pues tenemos que toquetear los dos. 105 00:11:23,370 --> 00:11:25,470 es parecido a lo que decíamos de comparables. 106 00:11:25,649 --> 00:11:27,549 ¿Vale? Hay una relación entre ellos. 107 00:11:28,230 --> 00:11:29,169 Si dos 108 00:11:29,169 --> 00:11:31,289 objetos dan true cuando 109 00:11:31,289 --> 00:11:33,250 lo pones como equals, o sea, si 110 00:11:33,250 --> 00:11:35,389 son iguales, tienen 111 00:11:35,389 --> 00:11:36,950 que dar el mismo Shcode. 112 00:11:38,149 --> 00:11:39,190 No puedo hacer 113 00:11:39,190 --> 00:11:40,950 que dos objetos 114 00:11:40,950 --> 00:11:43,129 distintos, dos instancias distintas, me den 115 00:11:43,129 --> 00:11:45,090 como resultado al equals 116 00:11:45,090 --> 00:11:47,289 true y como Shcode un número 117 00:11:47,289 --> 00:11:48,769 distinto. ¿Vale? 118 00:11:49,350 --> 00:11:51,409 Esto tiene las mismas implicaciones 119 00:11:51,409 --> 00:11:52,909 que hacíamos antes. O sea, 120 00:11:53,370 --> 00:12:01,210 Si equals es true, entonces mismo hashcode. 121 00:12:03,690 --> 00:12:14,190 Si tienen el mismo hashcode, no necesariamente implica que equals sea true. 122 00:12:16,049 --> 00:12:17,070 Pero lo tengo que comprobar. 123 00:12:17,990 --> 00:12:25,710 Cada vez que vosotros loqueteáis el equals, deberíais estar seguros que esta propiedad de aquí se cumpla. 124 00:12:26,730 --> 00:12:33,610 Y no puede dar problemas, sobre todo si usáis cosas que usan el hashcode, o usan, por ejemplo, el hashset. 125 00:12:34,710 --> 00:12:43,769 Yo entonces no lo entiendo realmente por qué. Para comprobar si los objetos son iguales, se comproba con el e-book o con el hashcode. 126 00:12:45,190 --> 00:12:47,409 ¿Y el hashcode realmente qué hace entonces? 127 00:12:47,549 --> 00:12:48,649 Ahora llegamos a eso. 128 00:12:48,750 --> 00:12:49,070 Ah, vale. 129 00:12:49,549 --> 00:12:55,870 El hashcode sabéis que existe, sabéis que tiene esta propiedad, pero no hemos entendido exactamente qué es el hashcode. 130 00:12:55,870 --> 00:13:02,990 Hemos hablado una vez, pero muy en paz, ahora voy a hablar de eso, ¿vale? 131 00:13:04,330 --> 00:13:07,289 Entonces, ¿dónde estoy? 132 00:13:09,480 --> 00:13:11,139 Esta es la interfaz set, ¿vale? 133 00:13:11,399 --> 00:13:18,299 Dentro de set, directamente hay hset y linkedhset, que son dos implementaciones de set, ¿vale? 134 00:13:18,820 --> 00:13:22,120 Hset es una implementación bastante buena, bastante rápida, ¿vale? 135 00:13:22,440 --> 00:13:26,480 Y esta de aquí es la misma, pero creo que esta se basa por debajo con una array, 136 00:13:26,480 --> 00:13:28,100 esta de aquí de por debajo con 137 00:13:28,100 --> 00:13:30,139 cosas alincadas, cada vez que es linked 138 00:13:30,139 --> 00:13:31,519 son objetos enlazados 139 00:13:31,519 --> 00:13:33,899 y luego está de set otra 140 00:13:33,899 --> 00:13:36,440 interfaz que es sorted set 141 00:13:36,440 --> 00:13:38,100 o sea un set ordenado 142 00:13:38,100 --> 00:13:40,379 del que nosotros veremos la implementación 143 00:13:40,379 --> 00:13:41,980 del triset, vale 144 00:13:41,980 --> 00:13:44,320 que este es el árbol, os acordáis que al principio vimos 145 00:13:44,320 --> 00:13:46,080 conjuntos 146 00:13:46,080 --> 00:13:48,059 está también, vimos 147 00:13:48,059 --> 00:13:52,340 lista, cola, pila y 148 00:13:52,340 --> 00:13:54,139 árbol, vale 149 00:13:54,139 --> 00:13:56,440 esta sería la implementación de árbol 150 00:13:56,480 --> 00:14:02,720 Ahora, antes de meternos aquí en el LashSet y ver las tres clases, 151 00:14:02,840 --> 00:14:06,419 sostancialmente aquí acabamos porque luego empieza el mapa, 152 00:14:06,799 --> 00:14:10,899 tenemos que entender qué es una FuncionAge. 153 00:14:12,220 --> 00:14:20,139 La FuncionAge es una función que se usa bastante en informática para varias cosas. 154 00:14:20,139 --> 00:14:24,100 Se utiliza para seguridad, se utiliza para almacenamiento, 155 00:14:24,220 --> 00:14:27,100 para mejorar la velocidad del almacenamiento y cosas por el estilo. 156 00:14:27,100 --> 00:14:40,840 ¿Y qué es? Sustancialmente es una función que categoriza objetos en un número, finito de números. 157 00:14:41,879 --> 00:14:58,860 Por ejemplo, imaginémonos que yo hago una función de x que me dice, pon 0 si x es par o 1. 158 00:14:58,980 --> 00:15:01,399 Si x es impar 159 00:15:01,399 --> 00:15:05,720 Este es un funcionar 160 00:15:05,720 --> 00:15:07,100 Fea 161 00:15:07,100 --> 00:15:08,620 Pero es un funcionar 162 00:15:08,620 --> 00:15:10,659 Porque tú me das cualquier número 163 00:15:10,659 --> 00:15:13,059 Y yo te lo puedo categorizar 164 00:15:13,059 --> 00:15:14,700 En la categoría 0 165 00:15:14,700 --> 00:15:16,620 O en la categoría 1 166 00:15:16,620 --> 00:15:18,220 ¿Sí? 167 00:15:19,120 --> 00:15:21,639 Una funcionar para que sea buena 168 00:15:21,639 --> 00:15:25,000 Tiene que tener pocas colisiones 169 00:15:25,000 --> 00:15:25,799 ¿Vale? 170 00:15:26,059 --> 00:15:27,820 Unas colisiones son cuando 171 00:15:27,820 --> 00:15:30,100 Dos objetos distintos 172 00:15:30,100 --> 00:15:40,720 caen en la misma categoría. En este caso, pésimo. ¿Vale? Porque había colisiones constantemente. 173 00:15:41,519 --> 00:15:46,320 Mitad de los números caerían en el 0, mitad de los números caerían en el 1. Por lo tanto, 174 00:15:46,320 --> 00:15:53,240 hay pocas categorías y muchas colisiones. ¿Sí? Vamos a ver otro ejemplo de esta función. 175 00:15:53,240 --> 00:16:00,730 Imaginaos una función que pilla un string 176 00:16:00,730 --> 00:16:11,669 Y genera una serie de categorías en base a la primera letra de este string 177 00:16:11,669 --> 00:16:16,230 Entonces si la letra es A, cae en la categoría A 178 00:16:16,230 --> 00:16:23,129 Si la primera letra es B, C, D, hasta Z 179 00:16:23,129 --> 00:16:25,269 más una que pondremos 180 00:16:25,269 --> 00:16:27,009 como asterisco, que es 181 00:16:27,009 --> 00:16:29,129 cualquier símbolo que no sea 182 00:16:29,129 --> 00:16:29,649 una letra. 183 00:16:30,909 --> 00:16:32,610 Entonces, si yo os pongo 184 00:16:32,610 --> 00:16:37,169 hola, ¿dónde se categoriza 185 00:16:37,169 --> 00:16:38,029 este señor aquí? 186 00:16:39,370 --> 00:16:40,350 En la H. 187 00:16:41,190 --> 00:16:43,090 ¿Sí? Como la primera 188 00:16:43,090 --> 00:16:44,990 letra es la H, me voy a la 189 00:16:44,990 --> 00:16:47,110 categoría H y lo pongo aquí. 190 00:16:47,529 --> 00:16:48,370 Aquí está hola. 191 00:16:51,419 --> 00:16:53,320 ¿Sí? Ahora pongo 192 00:16:53,320 --> 00:16:54,159 ¿cómo no? 193 00:16:55,779 --> 00:16:56,279 Gato. 194 00:16:57,159 --> 00:16:59,159 ¿Dónde va gato? 195 00:16:59,159 --> 00:17:06,160 Empieza por G, me iría a H, G, H, I, G, y aquí se pondría gato. 196 00:17:06,160 --> 00:17:26,019 Tú vas añadiendo palabras y las pones aquí. Aquí pones árbol, aquí pones banana, carro, etcétera, etcétera. 197 00:17:26,019 --> 00:17:38,140 Ahora, si os fijáis, con este sistema de aquí, si yo tengo, aquí tengo una, dos, tres, cuatro, cinco palabras ya metidas, ¿cuánto tardo en encontrar una de estas palabras? 198 00:17:39,039 --> 00:17:44,160 Imaginamos que busco DAT. ¿Cuánto tardo en encontrar DAT? 199 00:17:47,059 --> 00:17:54,420 Claro, o sea, muy rápido. Porque me quito de encima mirar todas las otras palabras. 200 00:17:54,420 --> 00:17:59,980 Ahora, si esto fuera una lista, yo debería recorrer toda la lista a la búsqueda de gato. 201 00:18:00,759 --> 00:18:04,380 Ahora, en vez de no lo hago, ahora digo, oye, gato, ¿por qué estás buscando gato? 202 00:18:04,460 --> 00:18:05,339 Vale, empieza por G. 203 00:18:05,480 --> 00:18:08,759 Espérate que me voy a la categoría G a ver si ahí está gato. 204 00:18:11,140 --> 00:18:13,500 Entonces, me quito de encima todos los otros. 205 00:18:14,759 --> 00:18:24,079 Lo que, mientras que no haya colisiones, la velocidad es constante. 206 00:18:24,500 --> 00:18:25,880 Es una operación. 207 00:18:26,119 --> 00:18:38,180 Cuanto mejor sea mi funcionage, cuanto mejor, cuanto más, técnicamente, dispersa es mi funcionage, ¿vale? 208 00:18:38,200 --> 00:18:44,000 Cuanto menos colisiones haya, mejor va lo que se basa sobre una función. 209 00:18:45,299 --> 00:18:51,930 Ahora, ¿qué pasa si quiero añadir gatito? 210 00:18:51,930 --> 00:19:00,940 Es que ahora iría en G, pero G ya está ocupado. 211 00:19:01,720 --> 00:19:02,539 Entonces, ¿qué hago? 212 00:19:03,579 --> 00:19:05,180 Y aquí depende, ¿vale? 213 00:19:05,779 --> 00:19:08,799 Algunas implementaciones lo que hacen es crear aquí una lista. 214 00:19:09,200 --> 00:19:10,500 Entonces, de gato voy a gatito. 215 00:19:15,799 --> 00:19:18,059 Y si lo traje, pues se pondrá aquí. 216 00:19:20,299 --> 00:19:21,359 ¿Qué pasa ahora? 217 00:19:21,619 --> 00:19:27,720 Que si busco esta palabra de aquí, pues me quito de encima todas las demás, 218 00:19:27,880 --> 00:19:30,119 que ya es una... estoy ganando bastante, 219 00:19:30,279 --> 00:19:33,539 pero ahora cuando llego a la G no hay un solo elemento, hay una lista. 220 00:19:33,680 --> 00:19:35,920 Entonces tengo que entrar en esa lista y buscar allí. 221 00:19:35,920 --> 00:19:40,339 Entonces cuantas más colisiones haya 222 00:19:40,339 --> 00:19:41,539 Peor 223 00:19:41,539 --> 00:19:43,500 ¿Entienden? 224 00:19:44,579 --> 00:19:45,579 Otra opción 225 00:19:45,579 --> 00:19:50,319 Yo tengo aquí mi hash 226 00:19:50,319 --> 00:19:51,400 Con mis categorías 227 00:19:51,400 --> 00:19:57,140 Si la función 228 00:19:57,140 --> 00:19:59,299 De lo que está insertando me mandaría 229 00:19:59,299 --> 00:20:01,339 Aquí, pues lo inserta aquí 230 00:20:01,339 --> 00:20:03,200 Si otra vez la función 231 00:20:03,200 --> 00:20:04,420 De lo que estoy buscando 232 00:20:04,420 --> 00:20:06,299 Otra vez, que no sé qué es 233 00:20:06,299 --> 00:20:09,000 Pues me manda al mismo sitio 234 00:20:09,000 --> 00:20:10,500 Y esto está ocupado 235 00:20:10,500 --> 00:20:13,220 pues me pongo a recorrer 236 00:20:13,220 --> 00:20:14,420 por abajo 237 00:20:14,420 --> 00:20:16,339 hasta encontrar una celda libre 238 00:20:16,339 --> 00:20:17,819 y lo pongo allí 239 00:20:17,819 --> 00:20:24,279 como siempre de la lista aquí el lateral 240 00:20:24,279 --> 00:20:26,839 pues usará esta misma estructura 241 00:20:26,839 --> 00:20:28,779 esta sería una tabla 242 00:20:28,779 --> 00:20:29,039 H 243 00:20:29,039 --> 00:20:32,539 para intentar insertar las cosas 244 00:20:32,539 --> 00:20:34,779 si tengo una colisión 245 00:20:34,779 --> 00:20:36,779 pues busco el primer hueco libre 246 00:20:36,779 --> 00:20:37,799 por debajo 247 00:20:37,799 --> 00:20:42,420 entonces cuando luego los buscaré 248 00:20:42,420 --> 00:20:44,559 yo me voy al sitio donde 249 00:20:44,559 --> 00:20:52,559 tengo que... debería estar, y si no está allí, voy buscándolo en las siguientes celdas hasta llegar 250 00:20:54,279 --> 00:21:01,480 a haberlo mirado todo y no haberlo encontrado. Pero si está, lo encuentro más rápidamente. 251 00:21:01,480 --> 00:21:10,900 ¿Entiendes? Entonces, una función hash, ¿qué es? Es una función que mapea objetos en números. 252 00:21:10,900 --> 00:21:15,000 y yo me voy aquí 253 00:21:15,000 --> 00:21:19,029 la función 254 00:21:19,029 --> 00:21:20,930 hashCode 255 00:21:20,930 --> 00:21:23,509 ¿vale? lo que te hace 256 00:21:23,509 --> 00:21:25,690 es pillarte el objeto porque tú harás 257 00:21:25,690 --> 00:21:27,269 this.hashCode o 258 00:21:27,269 --> 00:21:28,369 gato 259 00:21:28,369 --> 00:21:31,769 x es igual a new gato y luego harás 260 00:21:31,769 --> 00:21:33,650 x.hashCode, estás haciendo 261 00:21:33,650 --> 00:21:35,789 el hashCode de este x, de este objeto 262 00:21:35,789 --> 00:21:37,650 ¿vale? y el resultado es 263 00:21:37,650 --> 00:21:39,589 un entero, te doy un 264 00:21:39,589 --> 00:21:41,750 objeto, haz algo con él 265 00:21:41,750 --> 00:21:43,509 y dame un entero. 266 00:21:44,789 --> 00:21:46,390 Ese entero será 267 00:21:46,390 --> 00:21:48,130 el hash code, 268 00:21:48,269 --> 00:21:50,609 el código hash, que representa 269 00:21:50,609 --> 00:21:52,289 ese objeto. Teniendo en cuenta que 270 00:21:52,289 --> 00:21:53,750 las categorías son finitas 271 00:21:53,750 --> 00:21:55,990 y los objetos son infinitos. 272 00:21:57,710 --> 00:22:00,210 Entonces, colisiones siempre habrá. 273 00:22:01,950 --> 00:22:03,210 Cuanto más 274 00:22:03,210 --> 00:22:06,250 mi función hash 275 00:22:06,250 --> 00:22:08,609 sea buena y evite 276 00:22:08,609 --> 00:22:10,410 esta cosa y sea dispersa, 277 00:22:10,410 --> 00:22:12,490 mejor todo lo que se basa 278 00:22:12,490 --> 00:22:14,269 sobre hash, todo lo que tiene hash 279 00:22:14,269 --> 00:22:16,390 en el nombre, como los hash set 280 00:22:16,390 --> 00:22:17,750 como los hash map 281 00:22:17,750 --> 00:22:20,369 funcionará mejor, si mi 282 00:22:20,369 --> 00:22:22,329 función hash es 283 00:22:22,329 --> 00:22:24,349 pésima, pues también 284 00:22:24,349 --> 00:22:26,549 lo que 285 00:22:26,549 --> 00:22:27,329 voy a usar en el hash 286 00:22:27,329 --> 00:22:30,289 por ejemplo, una función hash code 287 00:22:30,289 --> 00:22:32,130 sería return 1 288 00:22:32,130 --> 00:22:34,490 perfecto 289 00:22:34,490 --> 00:22:36,210 todos van en la misma 290 00:22:36,210 --> 00:22:38,390 categoría, por lo tanto será lenta 291 00:22:38,390 --> 00:22:43,109 Ahora, hacer una función 292 00:22:43,109 --> 00:22:45,150 hash buena 293 00:22:45,150 --> 00:22:47,329 es complejo 294 00:22:47,329 --> 00:22:48,809 Se requiere 295 00:22:48,809 --> 00:22:50,730 conocimientos matemáticos, se requiere 296 00:22:50,730 --> 00:22:53,150 capacidad de pensar 297 00:22:53,150 --> 00:22:55,109 de cosas que 298 00:22:55,109 --> 00:22:57,069 yo una función hash 299 00:22:57,069 --> 00:22:59,170 buena no la sabría 300 00:22:59,170 --> 00:23:00,190 ¿Vale? 301 00:23:00,670 --> 00:23:02,950 Necesitaría estudiarme 302 00:23:02,950 --> 00:23:05,230 algunas cosas que son años que no estudio 303 00:23:05,230 --> 00:23:06,630 ¿Sí? 304 00:23:06,630 --> 00:23:09,269 entonces nosotros 305 00:23:09,269 --> 00:23:11,769 asumiendo que sabemos que existe 306 00:23:11,769 --> 00:23:12,990 y que está aquí 307 00:23:12,990 --> 00:23:15,009 pues lo que haremos es nos fiaremos 308 00:23:15,009 --> 00:23:16,710 de nuestro mejor amigo 309 00:23:16,710 --> 00:23:19,670 el señor Eclipse 310 00:23:19,670 --> 00:23:20,450 ¿vale? 311 00:23:20,849 --> 00:23:23,130 y cuando vosotros tenéis un objeto 312 00:23:23,130 --> 00:23:25,589 por ejemplo, yo tenía gato 313 00:23:25,589 --> 00:23:27,309 pues yo le puedo decir 314 00:23:27,309 --> 00:23:29,269 oye, me haces por favor 315 00:23:29,269 --> 00:23:30,569 el hashcode de gato 316 00:23:30,569 --> 00:23:33,230 y aquí surge 317 00:23:33,230 --> 00:23:35,789 aquí me dice 318 00:23:35,789 --> 00:23:43,829 genera asco del iguales y cuando él me lo crea me dice sobre qué quieres bajar el igual cuando 319 00:23:43,829 --> 00:23:50,069 los gatos son iguales yo podría decir cuando tienen el mismo nombre o cuando tienen el mismo 320 00:23:50,069 --> 00:23:57,970 peso o cuando tienen el mismo nombre y el mismo peso le doy a generate y él me crea por un lado 321 00:23:57,970 --> 00:24:04,049 el igual basado sobre lo que le da yo lo hemos analizado la última vez no aquí primero comprueba 322 00:24:04,049 --> 00:24:06,470 si estos son el mismo objeto entonces me da true 323 00:24:06,470 --> 00:24:08,750 si el objeto 324 00:24:08,750 --> 00:24:10,490 que le he pasado es null pues me dará 325 00:24:10,490 --> 00:24:12,390 false, si no son 326 00:24:12,390 --> 00:24:14,450 de la misma clase pues me dará false 327 00:24:14,450 --> 00:24:15,789 y si no 328 00:24:15,789 --> 00:24:17,990 hago un downcasting a gato 329 00:24:17,990 --> 00:24:20,230 y compruebo nombre 330 00:24:20,230 --> 00:24:22,109 con nombre y peso con peso 331 00:24:22,109 --> 00:24:25,849 ¿si? esto es el equal 332 00:24:25,849 --> 00:24:27,329 pero al mismo tiempo 333 00:24:27,329 --> 00:24:29,690 me ha dado esto 334 00:24:29,690 --> 00:24:33,180 que es sustancialmente 335 00:24:33,180 --> 00:24:35,299 beta la clase objects 336 00:24:35,299 --> 00:24:36,920 que es una clase 337 00:24:36,920 --> 00:24:39,420 de ayuda, ¿vale? Como 338 00:24:39,420 --> 00:24:41,500 arrays para clase 339 00:24:41,500 --> 00:24:43,019 de utilizar para los arrays, 340 00:24:43,680 --> 00:24:44,039 como 341 00:24:44,039 --> 00:24:47,319 aquí también 342 00:24:47,319 --> 00:24:49,339 usaba float, por ejemplo, como clase 343 00:24:49,339 --> 00:24:51,200 de la float. Pues, esto aquí son 344 00:24:51,200 --> 00:24:52,740 cosas para los objetos. 345 00:24:53,299 --> 00:24:55,160 Y te dice, me creas una función 346 00:24:55,160 --> 00:24:57,240 hash basado 347 00:24:57,240 --> 00:24:59,319 sobre el nombre y el peso. 348 00:25:00,940 --> 00:25:01,500 Así 349 00:25:01,500 --> 00:25:03,599 como tal y como me ha dado, 350 00:25:04,079 --> 00:25:05,119 ya me asegura 351 00:25:05,119 --> 00:25:07,599 que esta propiedad 352 00:25:07,599 --> 00:25:08,000 de aquí 353 00:25:08,000 --> 00:25:11,200 ha borrado. Que la propiedad 354 00:25:11,200 --> 00:25:13,079 de que si el equal 355 00:25:13,079 --> 00:25:15,279 se extruye, entonces en las cosas es lo mismo, 356 00:25:15,380 --> 00:25:17,220 se cumple. Esto se encarga de él. 357 00:25:17,539 --> 00:25:19,240 Si vosotros lo hacéis así y no lo 358 00:25:19,240 --> 00:25:21,440 tocáis, pues esto ya se cumple. 359 00:25:21,900 --> 00:25:22,859 Si vosotros 360 00:25:22,859 --> 00:25:25,259 tenéis que hacerlo vosotros 361 00:25:25,259 --> 00:25:27,339 a mano, no se os permite hacerlo 362 00:25:27,339 --> 00:25:29,000 así, pues entonces 363 00:25:29,000 --> 00:25:31,259 tendréis que tener cuidado vosotros. 364 00:25:31,759 --> 00:25:33,039 ¿Vale? Y buscar una 365 00:25:33,039 --> 00:25:45,180 funcionar aceptado. ¿Dudas? Si, claro, también te muestra cómo está implementado el hash, está llegando a un object. 366 00:25:45,180 --> 00:25:52,059 Si tú quieres saberlo, te vas a la clase Objects, te vas a hash y lees lo que está 367 00:25:52,059 --> 00:26:00,890 escrito ahí. Es que aquí es cuando la informática se da la mano a la 368 00:26:00,890 --> 00:26:07,869 matemática y salen cosas raras. Por eso muchas veces la gente que 369 00:26:07,869 --> 00:26:09,369 estudia matemática, luego 370 00:26:09,369 --> 00:26:11,750 se va a trabajar en informática. 371 00:26:12,410 --> 00:26:12,650 Porque 372 00:26:12,650 --> 00:26:15,809 nosotros se hablamos 373 00:26:15,809 --> 00:26:17,809 de programación, ¿vale? Muy bien. 374 00:26:17,910 --> 00:26:19,990 Pero cuando luego se va en algoritmica, 375 00:26:20,069 --> 00:26:22,069 cuando luego se tiene que hacer los derivados eficientes, 376 00:26:22,210 --> 00:26:23,990 cuando se tiene que hacer, pues por debajo 377 00:26:23,990 --> 00:26:25,869 está siempre un sustrato de 378 00:26:25,869 --> 00:26:27,569 matemática. 379 00:26:28,210 --> 00:26:29,670 Y si no sabes la matemática 380 00:26:29,670 --> 00:26:31,690 a alto nivel, pues allí 381 00:26:31,690 --> 00:26:33,950 no haces nada. Allí te fías 382 00:26:33,950 --> 00:26:36,109 de los que lo han hecho y dices 383 00:26:36,109 --> 00:26:37,170 ¡Hala! 384 00:26:37,869 --> 00:26:45,730 Luego, en la otra versión, como siempre, esta es una forma de hacer las cosas genéricas, 385 00:26:45,730 --> 00:26:55,029 entonces será buena, pero nunca tan buena como si tú te haces ad hoc para tu programa, 386 00:26:55,029 --> 00:27:00,309 para tu sistema, la funciona correcta. Entonces, si tú entiendes, si tú tienes un equipo de 387 00:27:00,309 --> 00:27:07,809 informáticos y matemáticos que trabajan juntos y que entienden del tema y que te sacan una 388 00:27:07,809 --> 00:27:16,269 funcional que para tu sistema es más eficiente que la que te da llamar mejor en un 95 por 389 00:27:16,269 --> 00:27:27,220 ciento de los casos no necesitas ese nivel de eficiencia pero y java o 390 00:27:27,220 --> 00:27:29,440 Objetes. 391 00:27:32,269 --> 00:27:32,609 A ver. 392 00:27:36,880 --> 00:27:38,920 An objects esta 393 00:27:38,920 --> 00:27:40,759 hash. Vale. 394 00:27:40,900 --> 00:27:42,819 Generate an hash code for a sequence of input 395 00:27:42,819 --> 00:27:43,240 values. 396 00:27:45,599 --> 00:27:47,039 Generate an hash code for a sequence 397 00:27:47,039 --> 00:27:48,880 of input values. The hash code is generated 398 00:27:48,880 --> 00:27:51,079 as if all the input values 399 00:27:51,079 --> 00:27:52,819 were placed into an array 400 00:27:52,819 --> 00:27:54,839 and that array were 401 00:27:54,839 --> 00:27:57,079 hashed by calling arrays.hashcode. 402 00:28:00,240 --> 00:28:00,720 This method 403 00:28:00,720 --> 00:28:03,259 is useful for implementing object.hashcode. 404 00:28:03,259 --> 00:28:14,259 Vale, o sea que esto, tú le pasas una serie de valores, él te hace un Array con esos valores y una vez que haces estos Arrays se llama Arrays.score y que hace Array.code. 405 00:28:14,259 --> 00:28:19,259 Array.code, el retorno de Arrays.code basado en los contextos de específicos Arrays. 406 00:28:19,259 --> 00:28:28,259 Si el Array contiene otros elementos de Arrays, el Arrays.code está basado en las entidades y los contextos. 407 00:28:28,259 --> 00:28:39,500 Pues me pierdo, ¿vale? Pues basados probablemente sobre la zona de memoria que tiene o cosas por el 408 00:28:39,500 --> 00:28:45,279 estilo, ¿vale? También, por ejemplo, si tú te vas a string, pues string tendrá su forma de hacer su 409 00:28:45,279 --> 00:28:51,539 hashcode, basado sobre los caracteres que tiene, cosas así. Cada clase tiene su forma. Entonces, 410 00:28:51,539 --> 00:28:56,680 luego, lo que solemos hacer nosotros es basarnos sobre esas implementaciones para hacer nuestro 411 00:28:56,680 --> 00:29:01,740 Yo tengo nombre que es un string, apellido que es un string, pillo nombre y apellido, 412 00:29:01,740 --> 00:29:07,660 llamo el hashcode de estos dos, lo sumo y ese es el mismo. Como para string funciona, 413 00:29:07,660 --> 00:29:21,890 pues funciona para mí también. Aún así, es demasiado alto nivel para nosotros de matemática 414 00:29:21,890 --> 00:29:29,329 de meternos a entrar en cómo hacer una función hash, cómo implementarla bien y cosas así. A mí 415 00:29:29,329 --> 00:29:35,710 lo que me interesa es que te entendáis este mecanismo de aquí, que es cómo funciona un 416 00:29:35,710 --> 00:29:43,910 HashSet. El HashSet tiene esta función Hash, tú le dices inserta este elemento, él pilla este elemento, 417 00:29:43,910 --> 00:29:51,529 lo va a llamar el HashCode de este elemento, recibe un número y este número es una categoría y él va 418 00:29:51,529 --> 00:29:59,210 a meterte ese objeto en esa categoría. Si varios objetos coinciden en el mismo número, los pondrá 419 00:29:59,210 --> 00:30:06,769 uno al lado del otro en una sorta de lista. Pero teniendo en cuenta que el hashCode es el 420 00:30:06,769 --> 00:30:12,470 numerito que viene después del arroba. Cuando nosotros hacemos el toString de object y sale 421 00:30:12,470 --> 00:30:20,710 la clase arroba y un numerito raro, pues ese es el hashCode. Entonces es un número bastante grande, 422 00:30:20,710 --> 00:30:26,049 en hexadecimal puede haber muchos valores. Entonces la idea es que los objetos, a menos 423 00:30:26,049 --> 00:30:32,529 que no sean millas o millones de objetos, pues sean bastante dispersos. Entonces, funciona bien. 424 00:30:33,670 --> 00:30:43,359 ¿Dudas? Bueno, entonces, nosotros tenemos H-Code. ¿Cuáles son las implementaciones de set? 425 00:30:43,359 --> 00:30:49,359 La primera implementación es H-Set. Es la implementación de una tabla H, de esta cosa 426 00:30:49,359 --> 00:30:55,480 aquí parecida. Una cosa así. Ahora no sé exactamente si luego los pone así o si luego 427 00:30:55,480 --> 00:31:01,480 los pone así. Pero el concepto es esto. Tengo una serie de categorías, las pongo allí y allí dentro 428 00:31:01,480 --> 00:31:09,400 asocio el valor. No permite tener elementos duplicados. Si voy a poner el mismo 429 00:31:09,400 --> 00:31:15,920 objeto, él se irá a la categoría, pide el hashcode, va a la categoría, mira allí y ve que ya está 430 00:31:15,920 --> 00:31:21,019 un objeto, hace un equals entre ellos, le da que es el mismo, te dice no lo añado. Ya está. 431 00:31:21,019 --> 00:31:25,980 es la implementación con mejor rendimiento 432 00:31:25,980 --> 00:31:27,799 de todas, pero no garantiza 433 00:31:27,799 --> 00:31:29,920 ningún orden a la hora de realizar iteraciones 434 00:31:29,920 --> 00:31:32,140 ¿vale? o sea, esta de aquí 435 00:31:32,140 --> 00:31:34,000 si a ti no te interesa el orden 436 00:31:34,000 --> 00:31:35,920 de entrega, el orden de inserción 437 00:31:35,920 --> 00:31:38,099 no te interesa el orden con el que 438 00:31:38,099 --> 00:31:40,160 están metidos 439 00:31:40,160 --> 00:31:41,980 dentro los objetos, no quieres 440 00:31:41,980 --> 00:31:43,539 ordenarlo de ninguna forma 441 00:31:43,539 --> 00:31:46,220 pues Hset es el que te da 442 00:31:46,220 --> 00:31:48,099 mejor resultado 443 00:31:48,099 --> 00:31:49,980 a nivel de rendimiento 444 00:31:49,980 --> 00:31:52,079 es el más rápido 445 00:31:52,079 --> 00:31:53,779 de todas las que hemos visto hasta ahora 446 00:31:53,779 --> 00:31:56,420 es más rápido, está claro que si yo digo 447 00:31:56,420 --> 00:31:58,200 no, pero yo quiero duplicar 448 00:31:58,200 --> 00:32:00,380 objetos, quiero que los objetos puedan ser duplicados 449 00:32:00,380 --> 00:32:01,920 pues ya la set no lo puedes usar 450 00:32:01,920 --> 00:32:04,420 no, pero yo quiero mantener 451 00:32:04,420 --> 00:32:06,400 un cierto orden, que sea un orden creciente 452 00:32:06,400 --> 00:32:08,680 de los objetos, pues ya la set no lo puedes usar 453 00:32:08,680 --> 00:32:10,460 la set, justo 454 00:32:10,460 --> 00:32:11,900 porque hace esta cosa aquí 455 00:32:11,900 --> 00:32:16,279 a lo mejor tú le das un objeto y te lo categoriza 456 00:32:16,279 --> 00:32:17,880 en el número 37, lo pone en la posición 457 00:32:17,880 --> 00:32:19,900 37, luego das otro objeto, lo categoriza 458 00:32:19,900 --> 00:32:21,599 en el 3, pues te lo pone en el 3. 459 00:32:21,920 --> 00:32:23,500 Luego otro objeto en el 94, 460 00:32:23,700 --> 00:32:25,460 en el 94. No hay un orden. 461 00:32:26,140 --> 00:32:27,720 Depende de su hash code 462 00:32:27,720 --> 00:32:29,599 que el número da. ¿Se entiende? 463 00:32:34,039 --> 00:32:35,339 Es la implementación más 464 00:32:35,339 --> 00:32:37,460 empleada debido a su rendimiento, y a que 465 00:32:37,460 --> 00:32:39,539 generalmente no nos importa 466 00:32:39,539 --> 00:32:41,000 el orden que ocupen los elementos. 467 00:32:41,299 --> 00:32:43,440 Yo tengo alumnos. No me 468 00:32:43,440 --> 00:32:45,740 importa dónde se pongan los alumnos 469 00:32:45,740 --> 00:32:47,380 siempre y cuando luego buscar 470 00:32:47,380 --> 00:32:48,380 estos alumnos es rápido. 471 00:32:50,019 --> 00:32:51,279 Entonces si me hago un hash set 472 00:32:51,279 --> 00:32:52,759 de alumnos, eso que digo. 473 00:32:53,579 --> 00:33:04,119 No puedo poner dos alumnos iguales, por lo tanto se queda la unicidad del alumno y cuando los vayan a buscar es el que con mejor rendimiento funcione. 474 00:33:05,559 --> 00:33:17,099 Ahora, si dijera, me das por favor esta misma, o sea, una lista de alumnos por fecha de matriculación. 475 00:33:17,099 --> 00:33:19,160 eso puede ser un infierno 476 00:33:19,160 --> 00:33:22,099 con el hash set 477 00:33:22,099 --> 00:33:24,680 porque no está allí dentro 478 00:33:24,680 --> 00:33:25,880 o sea, debería ir 479 00:33:25,880 --> 00:33:27,099 en cada 480 00:33:27,099 --> 00:33:30,180 elemento y ordenarlo yo 481 00:33:30,180 --> 00:33:36,259 esta implementación proporciona tiempos 482 00:33:36,259 --> 00:33:38,660 constantes en las operaciones básicas 483 00:33:38,660 --> 00:33:39,920 o sea, entrada y 484 00:33:39,920 --> 00:33:41,500 añadir y clicar 485 00:33:41,500 --> 00:33:44,460 siempre y cuando la función hash disperse 486 00:33:44,460 --> 00:33:46,200 de forma correcta los elementos 487 00:33:46,200 --> 00:33:57,019 dentro de la tabla h. Mientras que tú hagas una función h buena, los tiempos de insertar y quitar 488 00:33:57,019 --> 00:34:06,920 son constantes, que es lo mejor que puede hacer. No depende del número de elementos que has insertado. 489 00:34:06,920 --> 00:34:17,780 Si el tiempo fuera sobre n, si tú añades 100 elementos, pues el tiempo sería 100, n. Y cuando 490 00:34:17,780 --> 00:34:22,579 vas a buscarte en este elemento pensado a una lista vale en el caso peor de la lista que yo 491 00:34:22,579 --> 00:34:27,500 tengo que buscar un elemento pues debería recorrerme toda la lista encontrarlo el último 492 00:34:27,500 --> 00:34:33,619 entonces tengo 100 elementos tardaré 100 operaciones si tengo mil elementos tardaré 493 00:34:33,619 --> 00:34:43,239 mil operaciones en el caso peor este de aquí te da un tiempo de uno tú tienes mil elementos y esto 494 00:34:43,239 --> 00:34:49,539 encuentras la primera. Le das 10.000 elementos y él te la encuentra la primera. Si mi funcionage 495 00:34:49,539 --> 00:34:59,860 dispersa bien, pues con n elementos tú tardas siempre una operación. Mientras que al otro con 496 00:34:59,860 --> 00:35:11,480 n elementos tardabas n operaciones. ¿Entiendes? O sea que esto debería ser la elección de default. 497 00:35:11,480 --> 00:35:21,199 Ahora, si algo del HashSet no me vale, por ejemplo quiero duplicados o por ejemplo quiero un orden, 498 00:35:21,199 --> 00:35:33,260 pues entonces ya no quiero utilizar el HashSet y busco otra cosa. Entonces, preset. Esta 499 00:35:33,260 --> 00:35:38,900 implementación almacena los elementos ordenándolos en función de sus valores. Es bastante más lento 500 00:35:38,900 --> 00:35:44,659 que HashSet en el proceso de inserción. El tiempo de acceso y recuperación es bastante rápido, 501 00:35:44,659 --> 00:35:46,699 porque una vez que la ha ordenado 502 00:35:46,699 --> 00:35:48,639 según la ordenación 503 00:35:48,639 --> 00:35:50,159 que tiene que ordenarlo, pues luego 504 00:35:50,159 --> 00:35:52,400 como hay un orden, cuando tú buscas 505 00:35:52,400 --> 00:35:54,940 algo, pues él sabe más o menos dónde encontrarlo. 506 00:35:55,039 --> 00:35:56,599 ¿Vale? Porque buscar en una 507 00:35:56,599 --> 00:35:58,199 cosa ordenada es más fácil 508 00:35:58,199 --> 00:35:59,920 que buscar al azar. 509 00:36:00,980 --> 00:36:01,039 ¿Sí? 510 00:36:04,179 --> 00:36:05,300 Los elementos 511 00:36:05,300 --> 00:36:07,260 almacenados deben implementar la interfaz 512 00:36:07,260 --> 00:36:08,619 comparable. ¿Vale? 513 00:36:09,300 --> 00:36:11,079 Y esta implementación garantiza 514 00:36:11,079 --> 00:36:12,719 siempre un rendimiento de 515 00:36:12,719 --> 00:36:14,840 logDn. ¿Vale? 516 00:36:14,840 --> 00:36:17,519 en las operaciones básicas, debido a la estructura de árboles 517 00:36:17,519 --> 00:36:20,440 empleada para almacenar los elementos. 518 00:36:21,400 --> 00:36:22,900 Logaritmo de N es bueno. 519 00:36:23,519 --> 00:36:26,960 Si yo tengo 1000, tardo logaritmo 520 00:36:26,960 --> 00:36:30,059 de 1000 operaciones, que suele ser 521 00:36:30,059 --> 00:36:31,380 un número más bajo. 522 00:36:34,880 --> 00:36:37,340 Es una... 523 00:36:38,880 --> 00:36:40,519 Digamos que el rendimiento 524 00:36:40,519 --> 00:36:43,039 logarítmico es bueno. En el orden 525 00:36:43,039 --> 00:36:46,300 constante es el mejor. Logarítmico es bastante 526 00:36:46,300 --> 00:36:54,219 bueno. Orden de n está bastante bien. Orden de n al cuadrado empieza a ser complejo. Es 527 00:36:54,219 --> 00:37:00,139 cuando nosotros hacemos un for dentro de un for. Por cada elemento busco todos los otros 528 00:37:00,139 --> 00:37:04,400 elementos. Primero elemento busco todo. Segundo elemento busco todo. Tercer elemento busco 529 00:37:04,400 --> 00:37:12,880 todo. Pues esto es n al cuadrado. Si tengo 100 elementos, tardo 100% operaciones. Si 530 00:37:12,880 --> 00:37:15,719 Tengo mil elementos, tardo mil por mil operación. 531 00:37:17,139 --> 00:37:20,659 Y luego, lo peor que todo, es exponencial. 532 00:37:20,880 --> 00:37:22,699 Donde la n está al exponente. 533 00:37:24,719 --> 00:37:31,599 Operaciones o algoritmos que son del orden de la n exponencial, pues son de libre. 534 00:37:32,099 --> 00:37:33,820 Dos a la n, pues libre. 535 00:37:33,820 --> 00:37:40,639 Porque cuando tú tienes cien elementos, tardas dos a la cien operaciones. 536 00:37:41,380 --> 00:37:42,699 Dos a la cien es un número de libre. 537 00:37:42,880 --> 00:38:05,679 entonces el preset es el que está aquí abajo es este vale es el que me implementa el árbol 538 00:38:05,679 --> 00:38:13,179 vale entonces cuando yo tengo un nodo en el nodo pongo un objeto ese es el nodo raíz cuando añado 539 00:38:13,179 --> 00:38:20,099 un otro objeto lo comparo con este objeto si es menor lo pongo a la izquierda por ejemplo si es 540 00:38:20,099 --> 00:38:27,219 es mayor lo pongo a la derecha inserto otro pues si es menor lo inserta aquí si es mayor bajo aquí 541 00:38:27,219 --> 00:38:32,340 y miro esto si es menor que esto a la izquierda si es menor que esto a la derecha y voy construyendo 542 00:38:32,340 --> 00:38:37,619 un árbol así entonces una vez que construir un árbol así siempre y cuando tú números desordenados 543 00:38:37,619 --> 00:38:43,980 porque si me los das ya ordenados sale feo el árbol vale pues si tú me lo das al azar está 544 00:38:43,980 --> 00:38:49,619 metiendo alumnos se les pones así pues al final el árbol se balancea más o menos entonces llegar 545 00:38:49,619 --> 00:38:57,119 a la raíz del árbol, llegar al fondo del árbol, pues tardo logaritmo de n. O sea, tardo los niveles 546 00:38:57,119 --> 00:39:03,900 del árbol. Cada vez que elijo una rama u otra, pues me estoy quitando de buscar en toda la rama 547 00:39:03,900 --> 00:39:15,750 más cruda, ¿entiendes? Como un ejemplo. Como un ejemplo con números. Dame números de 1 a 100. 548 00:39:15,750 --> 00:39:36,090 77, lo pongo aquí. Otro. 41, es menor, lo pongo aquí. Otro. 77, menor, 41, menor, aquí. 35, 549 00:39:36,090 --> 00:39:40,050 Menor que 77, menor que 35, mayor que 2 550 00:39:40,050 --> 00:39:45,940 Aquí, 80, mayor que esto 551 00:39:45,940 --> 00:39:52,309 Aquí, 10 552 00:39:52,309 --> 00:39:58,690 Es menor que esto, es menor que esto, es mayor que esto, es menor que esto 553 00:39:58,690 --> 00:40:07,440 Iría aquí, digamos 78 554 00:40:07,440 --> 00:40:09,980 Pues menor que esto, menor que esto, 78 555 00:40:09,980 --> 00:40:14,619 95, pues mayor que esto, mayor que esto, 95 556 00:40:14,619 --> 00:40:19,119 78 no era mayor que 75 557 00:40:19,119 --> 00:40:26,019 78 es mayor que 77 558 00:40:26,019 --> 00:40:30,019 78 es mayor que 77 559 00:40:30,019 --> 00:40:33,400 Entonces, lo que estoy poniendo es este de aquí 560 00:40:33,400 --> 00:40:35,039 ¿Cómo? 561 00:40:35,739 --> 00:40:37,000 Menos a la izquierda 562 00:40:37,000 --> 00:40:39,280 Menos a la izquierda, mayor es a la derecha 563 00:40:39,280 --> 00:40:41,460 Por lo tanto, 77 está aquí 564 00:40:41,460 --> 00:40:42,860 Está allí, porque lo metí allí 565 00:40:42,860 --> 00:40:45,639 Esta es 78, lo que hago es moverla aquí. 566 00:40:46,940 --> 00:40:49,360 Entonces está el 80, es menor, 78. 567 00:40:50,159 --> 00:40:56,920 Otro número, 49, 77, va aquí, 41, aquí, 49. 568 00:40:59,840 --> 00:41:04,519 Luego están técnicas para rebalancear el árbol. 569 00:41:05,179 --> 00:41:08,320 Si veo que este aquí está yendo demasiado abajo, 570 00:41:08,320 --> 00:41:11,000 lo que puede hacer es pillar el 41 571 00:41:11,000 --> 00:41:13,179 y transformarlo, tirarlo arriba 572 00:41:13,179 --> 00:41:14,739 es decir, ahora el 41 573 00:41:14,739 --> 00:41:15,539 es el 574 00:41:15,539 --> 00:41:18,480 padre y 575 00:41:18,480 --> 00:41:20,820 el 77 se vuelve su hijo derecho 576 00:41:20,820 --> 00:41:22,800 y todos los demás, para evitar que una 577 00:41:22,800 --> 00:41:24,519 rama se quede demasiado profunda 578 00:41:24,519 --> 00:41:26,519 y que siempre sea el logaritmo 579 00:41:26,519 --> 00:41:27,980 esto que es matemática 580 00:41:27,980 --> 00:41:30,420 teoría de grafos 581 00:41:30,420 --> 00:41:33,000 teoría de árboles, y cosas por el estilo 582 00:41:33,000 --> 00:41:34,920 hay algoritmos 583 00:41:34,920 --> 00:41:36,179 que te pillan un árbol 584 00:41:36,179 --> 00:41:38,519 no balanceado 585 00:41:38,519 --> 00:41:40,360 y te lo transforman en un árbol 586 00:41:40,360 --> 00:41:42,960 equivalente pero balanceado 587 00:41:42,960 --> 00:41:44,320 con un mínimo paso 588 00:41:44,320 --> 00:41:46,239 con un mínimo trabajo 589 00:41:46,239 --> 00:41:48,199 entonces cuando el triset 590 00:41:48,199 --> 00:41:50,079 de vez en cuando se re-gestiona 591 00:41:50,079 --> 00:41:52,260 el dedo para que sustancialmente 592 00:41:52,260 --> 00:41:54,360 la profundidad sea baja 593 00:41:54,360 --> 00:41:56,539 ahora, ¿cuántos elementos he puesto? 594 00:41:57,019 --> 00:41:58,460 1, 2, 3, 4 595 00:41:58,460 --> 00:42:00,440 5, 6, 7, 8 y 9 596 00:42:00,440 --> 00:42:01,719 ¿vale? 597 00:42:02,260 --> 00:42:03,500 entonces en una lista 598 00:42:03,500 --> 00:42:05,559 debería hacer 9 599 00:42:05,559 --> 00:42:07,559 búsquedas para 600 00:42:07,559 --> 00:42:09,000 encontrar en el caso peor 601 00:42:09,000 --> 00:42:11,460 lo que yo quiero. Si lo que yo quiero está 602 00:42:11,460 --> 00:42:13,699 al final, haría 9 operaciones. 603 00:42:14,300 --> 00:42:15,519 Ahora el caso peor 604 00:42:15,519 --> 00:42:17,739 es 1, 2, 3, 4 y 5. 605 00:42:20,429 --> 00:42:21,429 O sea, el caso peor ahora 606 00:42:21,429 --> 00:42:22,130 es buscar 10. 607 00:42:23,510 --> 00:42:25,289 ¿Sí? Pero aún así 608 00:42:25,289 --> 00:42:27,269 son muchas menos operaciones, 609 00:42:27,429 --> 00:42:29,489 casi la mitad, que la que haría en una 610 00:42:29,489 --> 00:42:30,949 lista. En el caso peor. 611 00:42:30,949 --> 00:42:31,050 ¿Sí? 612 00:42:34,190 --> 00:42:36,489 ¿Y el 77 se le hará 613 00:42:36,489 --> 00:42:38,329 a raíz del árbol? En este caso 614 00:42:38,329 --> 00:42:47,570 sí porque la hemos metido al primer está claro que si yo uso un tricet y los doy ordenados y 615 00:42:47,570 --> 00:42:56,030 pongo el 1 y luego el 2 está aquí el 3 está aquí el 4 está aquí el 5 está aquí donde se me está 616 00:42:56,030 --> 00:43:02,489 saliendo la lista pero a este punto están estos sistemas que te digo que a un cierto momento como 617 00:43:02,489 --> 00:43:04,530 esto es muy balanceado, lo que hace es 618 00:43:04,530 --> 00:43:06,469 resetear, se pilla el 3, 619 00:43:06,590 --> 00:43:08,510 lo mete aquí, aquí pone el 2 620 00:43:08,510 --> 00:43:10,429 y el 1, y aquí pone el 4 621 00:43:10,429 --> 00:43:12,409 y el 5. Y ya 622 00:43:12,409 --> 00:43:13,909 esto funciona mejor que la lista. 623 00:43:17,559 --> 00:43:19,280 ¿En qué? En buscar. 624 00:43:22,090 --> 00:43:23,369 Posiblemente en insertar 625 00:43:23,369 --> 00:43:25,449 no, depende de cómo está hecho la lista. 626 00:43:27,869 --> 00:43:29,289 Pero una vez insertado 627 00:43:29,289 --> 00:43:31,210 como en orden, buscar es más 628 00:43:31,210 --> 00:43:32,769 la lista es 629 00:43:32,769 --> 00:43:35,610 orden de n operaciones 630 00:43:35,610 --> 00:43:37,489 mientras que el árbol 631 00:43:37,489 --> 00:43:39,650 es orden de logaritmo de n 632 00:43:39,650 --> 00:43:46,280 esto es mucho mejor 633 00:43:46,280 --> 00:43:48,199 que esto, porque esto en el caso 634 00:43:48,199 --> 00:43:49,679 pésimo, tienes que 635 00:43:49,679 --> 00:43:51,920 solo llegar a la profundidad del árbol 636 00:43:51,920 --> 00:43:54,280 y si tú lo rebalanceas con estas técnicas 637 00:43:54,280 --> 00:43:56,320 que hace, pues el árbol nunca 638 00:43:56,320 --> 00:43:58,039 será tan profundo 639 00:43:58,039 --> 00:43:59,920 como el número n 640 00:43:59,920 --> 00:44:02,300 será profundo como logaritmo de n 641 00:44:02,300 --> 00:44:06,599 pero estas son 642 00:44:06,599 --> 00:44:08,719 todas las cosas matemáticas que si nos interesa 643 00:44:08,719 --> 00:44:10,739 en la facultad 644 00:44:10,739 --> 00:44:12,039 uno de los primeros 645 00:44:12,039 --> 00:44:14,360 materias que estudiáis es 646 00:44:14,360 --> 00:44:16,260 calculabilidad y complejidad. 647 00:44:17,139 --> 00:44:18,760 ¿Vale? Que os enseñan 648 00:44:18,760 --> 00:44:20,960 a estimar la complejidad 649 00:44:20,960 --> 00:44:21,760 de lo que hacéis. 650 00:44:22,659 --> 00:44:24,820 Os enseño sustancialmente a no pongáis un for 651 00:44:24,820 --> 00:44:25,980 dentro de un for, dentro de un for. 652 00:44:30,960 --> 00:44:32,659 Y eso es muy interesante, muy... 653 00:44:32,659 --> 00:44:33,639 Me gustó mucho. 654 00:44:34,699 --> 00:44:36,659 Pero no es la cosa más sencilla. 655 00:44:39,590 --> 00:44:40,429 ¡Y ya está! 656 00:44:41,510 --> 00:44:41,909 ¿Vale? 657 00:44:41,909 --> 00:44:43,309 Este es el 3-set. 658 00:44:44,090 --> 00:44:44,690 Este de aquí. 659 00:44:45,710 --> 00:44:47,650 Luego estaría la link 660 00:44:47,650 --> 00:44:54,650 pero me interesa poco. Extiende Hset y contiene valores únicos, está implementada 661 00:44:54,650 --> 00:45:00,650 en función del orden de inserción. Aquí mantiene el orden de inserción. 662 00:45:00,650 --> 00:45:08,650 Permite elementos nulos. Es simplemente un poco más costosa que Hset. 663 00:45:08,650 --> 00:45:14,650 Luego estarían los maps, que no extienden collection y son otra cosa. 664 00:45:14,650 --> 00:45:22,210 cosas, son interfaz aparte, donde está el lashtable, lashmap, el trimap, pero nosotros 665 00:45:22,210 --> 00:45:34,110 por ahora los aparcamos y llegamos a esto. Esto es mi esquema de qué uso y empiezo aquí 666 00:45:34,110 --> 00:45:44,789 y digo lo que voy a guardar es valores, estoy guardando alumnos, estoy guardando gatos o 667 00:45:44,789 --> 00:45:49,050 pares, es decir, una clave y un valor añadido. 668 00:45:49,070 --> 00:45:57,489 Por ejemplo, yo quiero almacenar los DNI y que cada DNI se relacione con un alumno. 669 00:45:57,510 --> 00:45:58,889 Estos son los map. 670 00:45:58,909 --> 00:46:02,730 Por lo tanto, nosotros el lado izquierdo no lo miramos. 671 00:46:02,750 --> 00:46:04,369 Estos serían los map. 672 00:46:04,389 --> 00:46:06,170 Nosotros solo trabajamos con valores. 673 00:46:06,190 --> 00:46:07,329 Vale, me voy aquí. 674 00:46:07,349 --> 00:46:09,329 ¿Contiene duplicados o no? 675 00:46:09,349 --> 00:46:11,210 ¿Puede tener complicado o no? 676 00:46:11,230 --> 00:46:14,610 Si sí puede tener complicado, voy al revista. 677 00:46:14,610 --> 00:46:22,690 Si no contiene duplicado, me voy aquí y me pregunto, ¿su tarea principal es buscar elementos? 678 00:46:24,769 --> 00:46:28,070 Si no es buscar elementos, me voy a la lista igual. 679 00:46:29,489 --> 00:46:34,670 Si es buscar elementos, me voy aquí y me pregunto, ¿es importante mantener un orden? 680 00:46:35,610 --> 00:46:39,469 Si no es importante mantener un orden, me voy a ShSet y uso ShSet. 681 00:46:39,469 --> 00:46:50,690 Si es importante mantener un orden, me voy aquí y digo, es el orden de inserción, o sea, quiero mantener el orden con que he insertado los valores, o un orden propio del elemento. 682 00:46:51,210 --> 00:46:54,130 Si es de inserción, me voy al link de DashMap, a HSEP. 683 00:46:54,650 --> 00:46:57,929 Si es de ordenación, que defino yo, me voy al TRISEP. 684 00:47:05,159 --> 00:47:15,909 ¿Sí? ¿Nuda? Más o menos. 685 00:47:15,909 --> 00:47:21,909 Vale, en un 90% de las veces lo que vais a usar es o ARLIST o HSEP. 686 00:47:22,809 --> 00:47:29,809 ¿Criset también? Sí, 90% a relistarse. 687 00:47:29,809 --> 00:47:44,809 Yo la linked list la usas si quieres algo específico como una stack, una fifo, lifo y cosas por el estilo, entonces sí. 688 00:47:44,809 --> 00:47:55,650 Luego, se queda lo que os dije al principio. Si vuestro objetivo es recuperar datos, mejor una relista que una linked list. 689 00:47:56,010 --> 00:48:02,309 Si vuestro objetivo es insertar y quitar mucho, mejor una linked list que una relista. 690 00:48:02,409 --> 00:48:08,949 Pero normalmente, tú te creas un conjunto de datos y luego trabajas sobre esos datos. 691 00:48:08,949 --> 00:48:11,750 Entonces, la re-lista es más utilizada que la re-lista. 692 00:48:12,570 --> 00:48:19,030 Es más probable que un programa se cargue los datos y luego lo uses a que esté constantemente quitando, metiendo, quitando, quitando. 693 00:48:19,889 --> 00:48:22,010 Es un caso de uso más común. 694 00:48:23,570 --> 00:48:24,090 ¿Sí? 695 00:48:24,630 --> 00:48:27,730 Luego, esto no es definitivo. 696 00:48:28,210 --> 00:48:30,829 Es decir, es un poquito para orientaros. 697 00:48:31,210 --> 00:48:38,929 Pero no pilláis esto como, no, yo no voy a utilizar el LinkedIn List Map porque mi profesor me puso una vez una transparencia de PowerPoint. 698 00:48:38,949 --> 00:48:45,460 el point que decía que no se usa, pues no, ¿vale? ¿Dudas? 699 00:48:45,460 --> 00:48:52,280 O sea, es la tríceps o linker facet. ¿Cómo? 700 00:48:52,280 --> 00:48:58,280 Que nos hemos creado como contenido tríceps o linker facet. 701 00:48:58,280 --> 00:49:06,280 Linker facet que es igual a una facet solo que mantiene el orden de inserción, ¿vale? 702 00:49:06,280 --> 00:49:11,280 Hasta ahí. Hasta ahí. Hasta la transparencia 29 es donde hemos visto. 703 00:49:11,280 --> 00:49:12,480 a partir de la interfaz MAP, no.