"Hashmap -
Ventajas: Velocidad de consulta súper rápida y estructuras de datos que pueden alcanzar la complejidad del tiempo O (1) es HASHMAP. Datos de almacenamiento dinámico de longitud variable (en relación con las matrices).
Desventajas: el valor hash debe calcularse más, y si no se maneja correctamente, ocupará espacio adicional.
"Cómo usar hashmap -
Por lo general, usamos el hashmap de la siguiente manera
Map <integer, string> maps = new HashMap <Integer, String> (); maps.put (1, "A"); maps.put (2, "b");
El código anterior crea un nuevo hashmap e inserta dos datos. Los tipos de datos básicos no se aceptan aquí para hacer K y V.
Si escribe esto, habrá problemas:
Map <int, double> maps = new Hashmap <int, double> ();
¿Por qué usamos de esta manera? Consulte el código fuente:
clase pública Hashmap <K, V> extiende AbstractMap <K, V> Implementa el mapa <k, v>, clonable, serializable
Esta es la definición de la clase de implementación de HashMap.
"Hashmap es una estructura de datos de longitud variable dinámicamente
Al usar HashMap, para mejorar la eficiencia de la ejecución, a menudo establecemos la capacidad de inicialización de hashmap:
MAP <String, String> rm = new Hashmap <String, String> (2)
O use los mapas de clase de herramientas de Guava para crear fácilmente una colección e inicializar el valor con el tamaño apropiado.
Map <string, object> map = maps.newhashmapwithEppectedSize (7);
Entonces, ¿por qué usarlo así? Veamos su constructor de origen.
Constructor sin parámetros:
public Hashmap () {this.loadFactor = default_load_factor; Threshold = (int) (default_initial_capacity * default_load_factor); table = nueva entrada [default_initial_capacity]; init (); } pública hashmap () {
this.loadfactor = default_load_factor;
Threshold = (int) (default_initial_capacity * default_load_factor);
table = nueva entrada [default_initial_capacity];
init ();
}
/** * construye un <tt> hashmap </tt> vacío con la capacidad inicial * especificada y el factor de carga predeterminado (0.75). * * @param InicialCapacity La capacidad inicial. * @throws ilegalArgumentException si la capacidad inicial es negativa. */ public hashmap (int InitialCapacity) {this (inicialCapacity, default_load_factor); }Explicación de sustantivos:
Default_load_factor // factor de carga predeterminado, 0.75 si no se especifica. Default_initial_capacity // Capacidad de inicialización predeterminada, predeterminado es 16 umbral // El valor de umbral (YU) se calcula en función del factor de carga y la capacidad de inicialización. <span style = "color: RGB (54, 46, 43); Font-Family:" Microsoft Yahei ";"> El umbral significa que cuando el tamaño de Hashmap es mayor que el umbral, la operación del cambio de tamaño se realizará.
Entonces sabemos que si llamamos al constructor sin parámetros, obtendremos una matriz de 16 capacidad.
Entonces, la pregunta es: ¿qué pasa si la capacidad inicial no es suficiente?
Las matrices son de longitud fija, ¿cómo usar datos de longitud fija para representar datos de longitud incierta? La respuesta es encontrar una más larga, pero reduce la eficiencia cuando cambia de tamaño. Por lo tanto, recomendamos que hashmap tenga una capacidad confiable al inicializar.
"Método Put de Hashmap -
public v put (k key, V value) {if (key == null) // Si la clave está vacía, una diferencia entre hashmap y hashtable returs PutfornullKey (valor); int hash = hash (key.hashcode ()); // enmarca el valor hash basado en el húsico de la clave int i = indexfor (hash, table.length); // enmarca el subíndice de la matriz para poner en función del valor hash para (entrada <k, v> e = table [i]; e! = Null; e = e.next) {// todo para el bucle implementa que si k existe, luego reemplace v objeto k; if (e.hash == hash && ((k = e.key) == key || key.equals (k))) {v OldValue = e.Value; e.value = valor; E.RecordAccess (esto); devolver OldValue; }} modcount ++; // contador adicional (hash, clave, valor, i); // agregar a la matriz return null; }Si los datos insertados exceden la capacidad existente, se ejecutará
Addentry (hash, clave, valor, i);
Void Addentry (int hash, k key, v valor, int bucketIndex) {Entry <k, v> e = table [bucketIndex]; tabla [bucketIndex] = nueva entrada <k, v> (hash, clave, valor, e); if (size ++> = umbral) <span style = "color:#ff0000;"> <strong> resize (2 * table.length);}Aquí, si se muestra el umbral de tamaño actual ++>, se ejecutará el tamaño actual dos veces y cambiará el tamaño (2*Tabla.length). Entonces, ¿cómo se expanden?
Void reize (int newCapacity) {Entry [] OldTable = table; int if (OldCapacity == Maximum_Capacity) {Umshold = Integer.max_value; devolver; } Entrada [] newtable = nueva entrada [newCapacity]; <span style = "Color: RGB (51, 51, 51); Font-Family: Arial;"> nueva una nueva matriz, </span> <strong> <span style = "color:#ff0000;"> transferir (newtable); </span> </strong> // transferir la matriz a una nueva tabla de Array = NewTable; umbral = (int) (newCapacity * LoadFactor); // Recalcular la capacidad}¿Cómo se transfiere la transferencia de la matriz de transferencia?
transferencia void (entrada [] newtable) {Entry [] src = table; int newCapacity = newtable.length; for (int j = 0; j <src.length; j ++) {Entry <k, v> e = src [j]; if (e! = null) {src [j] = null; do {Entry <k, v> next = e.Next; int i = <strong> <span style = "color:#ff0000;"> indexfor (e.hash, newCapacity); // Recalcule el índice basado en la capacidad de valor hash </span> </strong> e.next = newtable [i]; Newtable [i] = E; e = siguiente; } while (e! = null); }}}"El número de ejecuciones adicionales de expansión de hashmap-
Entonces, si queremos agregar un hashmap de 1000 elementos, si usamos el valor predeterminado, ¿cuántos cálculos adicionales necesito calcular?
Cuando es mayor que 16*0.75 = 12, debe recalcularse 12 veces
Cuando es mayor que 16*2*0.75 = 24, se requieren 24 cálculos adicionales.
...
Cuando es mayor que 16*n*0.75 = 768, se requieren 768 cálculos adicionales.
Entonces calculamos 12+24+48+...+768 veces en el proceso de expansión
Por lo tanto, se recomienda encarecidamente que especifiquemos manualmente el tamaño inicial si conocemos el alcance en el proyecto como este:
Map <integer, string> maps = new HashMap <Integer, String> (1000);
Resumen: Esta es la razón por la cual la eficiencia de ejecución de HASHMAP se reduce severamente si excede la capacidad inicial durante el uso.
Lo anterior tiene que ver con el uso de HashMap en este artículo sobre el análisis del código fuente de Java, espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!