HashMap, HashTable, ConcurrentHashMap, apréndalos en comparación

Similitudes y diferencias entre HashMap y HashTable

1. Similitudes:

  1. Según la implementación de la tabla hash, una matriz de entrada para almacenar datos se mantiene internamente, y cada elemento es un par clave-valor, y los conflictos se resuelven mediante una lista enlazada individualmente dentro de los elementos.
  2. Cuando la capacidad de la matriz de entrada no es suficiente, se cambiará de tamaño. El tamaño es el número de ranuras utilizadas en la matriz subyacente. Umbral = capacidad * factor de carga (el valor predeterminado es 0,75) es el umbral. Cuando el tamaño es mayor que el umbral, se expandirá. Cree una nueva matriz inferior y luego vuelva a agregar todos los elementos de la matriz original a la nueva matriz, necesita recalcular la posición.
  3. Implementar la interfaz serializable, que se puede serializar; implementar la interfaz Cloneable, que se puede clonar
  4. Ambos contienen los métodos containsKey y containerValue
  5. Todos implementan la interfaz del mapa

2. Diferencias:

  1. La herencia de la clase principal es diferente. HashMap hereda la clase AbstractMap y Hashtable hereda la clase Dictionary (obsoleta)
  2. Hashmap no tiene un método contenedor, Hashtable sí
  3. HashMap permite que tanto la clave como el valor sean nulos, pero Hashtable no lo es
  4. El método para calcular el valor hash es diferente:
    HashMap: (h == key.hashcode ()) ^ (h >>> 16)
    Hashtable: key.hashcode ()
  5. El mecanismo de expansión es diferente:
    HashMap: la capacidad predeterminada es 16 y cada expansión es el doble de la capacidad del arreglo original
    Hashtable: la capacidad predeterminada es 11 y cada expansión es dos veces +1 del arreglo original.
  6. La posición del índice de cálculo es diferente:
    HashMap:
int hash = hash(key)
int index = indexFor(hash, length)
int hash(object x){
	int h = x.hashcode();
	h += ~(h << 9);
	h ^= (h >>> 14);
	h += (h << 4);
	h ^= (h >>> 10);
	return h;
}
int indexFor(int h, int length){
	return h&(length - 1);
}

Tabla de picadillo:

int index = (key.hashcode() & 0x7FFFFFFF) % length
  1. Hashmap no es seguro para subprocesos, Hashtable es seguro para subprocesos, la mayoría de los métodos en Hashtable están sincronizados

El nacimiento de ConcurrentHashMap

Compuesto por la matriz de segmentos y la matriz HashEntry, el segmento es un bloqueo reentrante reantrantLock.

  1. Inicialización: el parámetro de entrada initialCapacity es la capacidad inicial, el valor predeterminado es 16, loadFactor es el factor de carga de cada segmento, el valor predeterminado es 0,75
  2. Obtener operación: hash primero, use el valor para ubicar el segmento a través de la operación hash y luego ubique el elemento a través del algoritmo hash.
    Nota: la operación de obtención no está bloqueada. Las variables compartidas que se utilizarán en el método get se definen como volátiles, como el campo de recuento para contar el tamaño del segmento actual y el valor del valor de HashEntry utilizado para almacenar el valor. Definida como volátil, la visibilidad se mantiene entre subprocesos y es leída por varios subprocesos al mismo tiempo.
  3. Poner operación: se debe agregar un bloqueo al operar variables compartidas, primero ubique el segmento y luego inserte la operación en el segmento.
    Inserción: 1. Determine si es necesario expandir la matriz HashEntry en el segmento: Antes de insertar, determine si excede el umbral y, si lo excede, expanda. A diferencia de HashMap, Hashmap determina si el umbral se alcanza después de la inserción. Si alcanza el umbral, el problema es que puede que no haya nuevos elementos insertados después de la expansión y la expansión no es válida. 2. Localice la posición e insértela.
  4. Operación de tamaño: Primero intente dos veces para contar el tamaño del segmento sin bloquear el segmento. Si el conteo del contenedor cambia, utilice el método de bloqueo para contar todos los tamaños de segmento. Entonces, cómo juzgar si el contenedor cambia durante las estadísticas: use la variable modCount, antes de los elementos de operación put, remove y clean, se comparará la variable modeCount + 1, antes y después del tamaño de las estadísticas, compare si modCount ha cambiado.

Supongo que te gusta

Origin blog.csdn.net/yearningseeker/article/details/105764793
Recomendado
Clasificación