Hablando de HashMap

1. ¿El principio subyacente de HashMap (basado en jdk8)?

La esencia de HashMap se basa en matrices y listas enlazadas. Aprovecha al máximo la consulta rápida de matrices y la rápida adición y eliminación de listas enlazadas. Al igual que las listas enlazadas, simplemente cambie el puntero. La matriz almacena cada
objeto de nodo y el nodo de nodo incluye hash, clave, valor y siguiente. Determine el subíndice del Nodo almacenado en la matriz a través del valor hash de la clave. El valor hash se obtiene
mediante desplazamiento y XOR mediante el método hashCode () de la clave . El propósito es reducir la colisión hash, y luego mediante el valor hash y la capacidad del HashMap- 1 Realice la operación & para obtener el subíndice del arreglo, anteriormente se
obtenía por% operación, por eso la capacidad del HashMap es 2 elevado a la n. Si el elemento de la matriz está vacío, insértelo directamente. Si no está vacío
, compárelo de acuerdo con el valor hash de la clave y el método equals (). Esta es también la razón por la que la consulta HashMap es rápida. Si es diferente , se coloca en la lista vinculada.Si la longitud de la lista vinculada es mayor que 8, se puede convertir a árbol rojo-negro.

/**
 * 通过key的hashCode()值进行位移和异或运算,降低哈希碰撞
 */
static final int hash(){
	int h;
	return (key==null)? 0:	(h=key.hashCode())^(h>>>16);
}

2. ¿Cuál es la diferencia y la conexión entre hashCode () y equals () en Object? ¿A qué debo prestar atención cuando la clave de HashMap es un tipo de referencia?

hashCode () asigna la dirección, el campo y otra información del objeto en un valor hash de tipo int de acuerdo con ciertas reglas. equals () es comparar la dirección del objeto, si el objeto tiene
la misma dirección, entonces el valor hashCode () debe ser igual al valor de hashCode () no es igual, entonces los dos objetos no deben querer esperar, esto es put y get HashMap primero juzgará si los
valores hash son iguales y luego comparará la razón con equals ().
Los métodos equals () y hashCode () se reescribirán, porque la búsqueda se basa en si el valor hash de la clave y la dirección son iguales para determinar si es el mismo elemento. Si no lo reescribe,
debe obtener un nulo.

3. ¿Qué es una colisión de hash?

Fenómeno en el que diferentes objetos generan el mismo valor hash a través de una función hash.

4. ¿Por qué la longitud de HashMap 2 es elevada a la potencia de n? ¿Cuáles son las funciones de la operación de cambio y la operación XOR en la función hash ()?

El valor generado por hash () es exactamente el mismo que la n-ésima potencia de 2 y la operación & para obtener el subíndice de la matriz. La eficiencia de & operación es mayor que% de operación.
La operación de desplazamiento y la operación XOR en la función hash () son para reducir las colisiones hash y evitar almacenar en el mismo subíndice de matriz de HahsMap.

5. ¿Cómo implementar el método put y la expansión de capacidad de HashMap?

put ()
1. Determine si el HashMap está vacío o si la longitud es 0, que es para inicializar la expansión.
2. Determine el subíndice de la matriz de acuerdo con el valor hash de la clave. Si el valor correspondiente es nulo, inserte el objeto directamente, de lo contrario compare si la clave existe (por valor hash () y dirección), y hay una sobrescritura.
3. Si no existe, determine si es un número rojo-negro o una lista enlazada. El árbol rojo-negro se inserta directamente y luego el árbol rojo-negro está balanceado. Si es una lista enlazada, el La lista se atraviesa, hay cobertura, no hay inserción y la
longitud de la lista vinculada es mayor que 8 y se convierte en árbol rojo-negro.
4. Cuando el tamaño sea mayor que el factor de carga de


capacidad 0,75, expanda la capacidad. resize () 1. Cuando la longitud del HashMap sea 0, inicialícelo y la capacidad predeterminada es 16. 2. Cuando la longitud de HashMap es mayor que el factor de carga de capacidad de 0,75, expanda la capacidad y la longitud de la matriz después de la expansión es el doble de la original, y el elemento está en la posición actual o en la posición después del subíndice actual se duplica.
Inserte la descripción de la imagen aquí

/**
 * jdk1.8HashMap中的put方法
 */
 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)     /*第一次扩容*/
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))      /*判断key是否存在*/
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();   /*第二次扩容*/
        afterNodeInsertion(evict);
        return null;
    }

6. ¿Cuál es la diferencia entre Java7 y Java8 HashMap?

1. Array + lista enlazada ------> Array + lista enlazada + árbol rojo-negro
2. El valor de hash () 9 perturbaciones ------> 2 perturbaciones de desplazamiento y operación OR exclusiva
3. Interpolación de cabeza método- -----> Método de desconexión para evitar el enlace muerto

7. ¿Cuál es la diferencia entre HashMap y HashTable?

1. HashTable está decorado con Synchronized y es seguro para subprocesos. HashMap no es seguro para subprocesos, por lo que la eficiencia será mayor que HashTable.
2. La clave de HashTable no puede ser nula y la clave de HashMap puede ser nula.

8. ¿Por qué no es seguro el hilo de HashMap?

El método put provocará la sobrescritura de datos. Suponiendo que A y B son dos subprocesos, se ejecuta un subproceso para determinar si hay un segmento de tiempo de código de la clave, el subproceso B inserta la misma clave,
A sobrescribirá el valor de B y el subproceso ocurre la inseguridad.

9.ConcurrentHashMap?

Resolver después de aprender conocimientos relacionados con la concurrencia, continuará ...

Supongo que te gusta

Origin blog.csdn.net/shiquan202101/article/details/111751384
Recomendado
Clasificación