El análisis en profundidad de la diferencia entre HashMap y Hashtable

I. Introducción

  El mes pasado, se tomó un tiempo para estudiar un poco HashMapdel código fuente de HashMapla aplicación de los principios tienen una mayor comprensión en profundidad de hoy de repente pensar en una prueba a menudo se enfrentan con cuestiones - HashMapcon Hashtableuna diferencia, por lo que tomó un tiempo para estudiar un poco Hashtablefuente. Hoy en día, en este blog para explicar brevemente la diferencia entre los dos, lo siguiente será sobre todo desde el Hashtablepunto de vista, describirlo y HashMapcuál es la diferencia, y se describirá en dos aspectos - el uso de términos y detalles de realización . Si HashMapno es muy comprensivo, se puede leer acerca de este blog: HashMap Interpretación fuente - la comprensión de la profundidad HashMap causa eficiente .


En segundo lugar, el texto

 Las diferencias de 2.1

(1) Hashtable thread-safe, HashMap hilo-inseguro

  Esta es la diferencia fundamental entre los dos vasos. HashMapEs un contenedor seguro para subprocesos, que no implementa la sincronización de hilos, por lo que no se debe utilizar en un entorno multiproceso. La Hashtablerealización de la sincronización de hilos, es un contenedor seguro para subprocesos, pero compara manera sincronizada mal - la adición sincronizada palabra clave directamente en la mayoría de los métodos públicos para sincronizar , por lo que para los mismos Hashtableobjetos, que sólo puede tener una subproceso llama que un método de instancia. De esta manera torpe que el sincronizada Hashtableeficiencia es mucho menor que HashMap, y en muchos casos, esta sincronización no tiene sentido, como en el caso de una operación de escritura no está ocurriendo, pueden simultáneamente múltiples hilos de Hashtableleer, y no causará daño.

(2) Hashtable permitió clave o el valor es nulo, lata HashMap

  En Hashtablemuchos sentidos, el (como el putmétodo), condenado especial valuepara la nullsituación, momento en el que un tiro directo NullPointerException; Para keyque nullla situación no tiene sentencia especial, pero si se añade en una keyde las nullelementos, siendo los tiros NullPointerException, desde Hashtablela adquisición keyde hashlos valores es llamar a la directa key.hashCodemétodo, todo keyno puede ser null. Vemos Hashtableel putmétodo para saber (se borra el código adicional):

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // ......
    int hash = key.hashCode();

    // ......
}

  Sin embargo HashMap, si se trata keyo value, se puede pensar null, ya que nullhizo un tratamiento especial. HashMapImplementación, el juez keyes null, no va a ser llamado key.hashCodepara obtener su hashvalor, sino más bien 0como su hashvalor, y en el getmétodo de adquirir value, si no se encuentra el nodo null, entonces el retorno directo null, de lo contrario node.value. Busque también en HashMaplas dos piezas de código para verificar lo siguiente:

// 此方法为HashMap中获取key的hash值的方法,特判了key == null的情况
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

// HashMap中的get方法,特判了value为null的情况
public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

 2.2 darse cuenta de las diferencias en los detalles

(1) la cabeza Hashtable utilizando interpolación, la interpolación HashMap usando la cola después de JDK1.8

  hablar brevemente sobre lo que es el primer enchufe y el final del juego:

  • El primer método de interpolación: Insertar un nuevo nodo en la lista vinculada, la lista enlazada el nuevo nodo como el nodo primario, y el nuevo nodo nextapunta al nodo de cabecera de edad;
  • Tail Interpolación: Cuando se inserta un nuevo nodo en la lista, por lo que el final de la lista de nodos vinculados nextpuntos al nuevo nodo;

  HashtableEn primer lugar se utiliza la interpolación, pero HashMapen JDK1.8el uso anterior es la interpolación cabeza. Sin embargo, se encontró que en el caso concurrente, si no hay sincronización de subprocesos, el primer método de interpolación hay una pequeña probabilidad dará lugar a un bucle infinito (no voy a empezar a este problema se describe, puede ir a buscar hacia arriba), por lo que desde el JDK1.8principio, como HashMapla adición de un nodo hasta el final de la interpolación.

(2) Capacidad HashMap debe ser 2 ^ n, y la capacidad no es el límite Hashtable

  Esta es una diferencia muy grande entre los dos, en este punto, por lo que HashMapy Hashtbleson muy diferentes en su aplicación. HashMapLa capacidad debe ser 2^nla razón por la que recomiendo en el blog prefacio que hizo una descripción detallada, simplemente haga clic aquí. Capacidad como 2^nse hace con el fin de optimizar el módulo aritmético como 2^npara satisfacer una propiedad:

Seguramente% 2 ^ n == si, y (2 ^ n - 1)

  Ya sea HashMapo Hashtable, para obtener el índice de nodo de la matriz, necesidad de utilizar keyel hashvalor de módulo de la longitud de la matriz, y HashMapel límite de longitud de la matriz 2^n, es utilizar la fórmula anterior &Alternativamente %realizado operación de módulo, porque &eficiente que %superior, mientras que la adquisición de índice es una operación frecuente, por lo que este paso se optimiza de manera que HashMapla velocidad de búsqueda se ha mejorado mucho. En el Hashtablemedio, que es el uso directo %de más de toma. Vemos más de cualquier fuente:

// HashMap中的取余:tab为存放节点的数组,n为数组长度,hash变量存的是key的哈希值
// 这一步就是获取哈希值为hash的key在tab中的位置
// HashMap中的hash值不会是负数,因为HashMap中自己实现了hash方法求hash值
tab[(n - 1) & hash]

// Hashtable中的取余:hash & 0x7FFFFFFF其实就是取hash的绝对值,然后直接对tab.length取余
// 0x7FFFFFFF转换成二进制就是第一位为0,后31位为1,这个操作也就是将符号位转为0(第一位为符号位),
// 而二进制中,符号位为0表示表示正数,这一步是防止计算出负数的下标,因为hash值可能为负
// 不用Math.abs是因为Math.abs(Integer.MAX_VALUE)越界,结果还是负数
int index = (hash & 0x7FFFFFFF) % tab.length;

  Y es esta optimización, lo que lleva HashMapy Hashtablemuchas otras diferencias:

  • HashMapLa capacidad inicial por defecto 16, es decir 2^4, si una capacidad especificada es HashMapno usarlo directamente, pero primero encontrar la primera es mayor que la capacidad especificada 2^ny; Hashtablecapacidad inicial por defecto 11, 11es un número primo, de acuerdo con hashlos requisitos escala de tiempo, de modo que el siguiente número primo se puede asignar subíndice más uniforme, Hashtableque recibe directamente la capacidad inicial especificada;
  • HashMapDirectamente a la tamaño de la matriz multiplicado cuando la expansión 2, ya que (2^n)×2 == 2^(n+1), aún así cumplir 2^n; y Hashtableexpansión Shi 乘2加1, ya que permite una gran probabilidad número primo o un número primo;

(3) JDK1.8 comenzó, estructura de la cadena HashMap + en una matriz de árbol + rojo-negro

  En JDK1.7el pasado, HashMapy Hashtablela estructura es una implementación de matriz + lista enlazada, pero desde el JDK1.8principio, HashMapen una lista enlazada de arrays + + árbol rojo-negro. Esto es porque, en el hashcaso en el que la irregularidad de módulo resultado, el nodo puede ser concentrada en unos pocos array lista, resultando en una larga lista. Por ejemplo, un ejemplo extremo, todos los nodos hashcalculan los valores de índice son iguales, entonces todos los nodos en una lista enlazada, esta vez HashMapo Hashtablea degenerar en una lista enlazada, la complejidad de tiempo de consulta para la degradación O(n). Para evitar que esto suceda, desde el JDK1.8principio, HashMapen Si una lista enlazada de nodos alcanzó 8uno, puso esta lista se convierte en un árbol rojo-negro, esta vez, recogidos en este artículo la eficacia de las consultas a partir O(n)promovido O(logn). Y Hashtablecomo un contenedor obsoleta, la naturaleza no se tomará el tiempo para optimizar su complejo.


En tercer lugar, el resumen

  HashtableEs un buque obsoleto, en el desarrollo, que debe ser inferior a usarlo, o simplemente no lo usamos. En el entorno de un solo roscado, que usaríamos HashMap, pero en un entorno multiproceso, debe ser usado ConcurrentHashMap, su eficiencia es mucho mayor Hashtable. Algunos mencionado en último lugar son relevantes y lograr HashMap, recomiendo leer las recomendaciones en el blog prefacio para HashMapla aplicación específica.


En cuarto lugar, la referencia

Supongo que te gusta

Origin www.cnblogs.com/tuyang1129/p/12578933.html
Recomendado
Clasificación