Para ponerlo más simple (tanto como pueda más simple) + algunos detalles más.
Estas propiedades dependen de muchas cosas internas que serían muy interesantes de entender, antes de pasar a ellas directamente.
TREEIFY_THRESHOLD -> cuando un solo cubo alcanza esto (y el número total excede MIN_TREEIFY_CAPACITY
), se transforma en un nodo de árbol rojo / negro perfectamente equilibrado . ¿Por qué? Debido a la velocidad de búsqueda. Piense en ello de otra manera:
se necesitarían como máximo 32 pasos para buscar una entrada dentro de un depósito / contenedor con entradas Integer.MAX_VALUE .
Alguna introducción para el próximo tema. ¿Por qué la cantidad de contenedores / cubos es siempre una potencia de dos ? Al menos dos razones: más rápido que la operación de módulo y módulo en números negativos será negativo. Y no puede poner una Entrada en un depósito "negativo":
int arrayIndex = hashCode % buckets; // will be negative
buckets[arrayIndex] = Entry; // obviously will fail
En cambio, se usa un buen truco en lugar de módulo:
(n - 1) & hash // n is the number of bins, hash - is the hash function of the key
Eso es semánticamente lo mismo que la operación de módulo. Mantendrá los bits inferiores. Esto tiene una consecuencia interesante cuando lo haces:
Map<String, String> map = new HashMap<>();
En el caso anterior, la decisión de a dónde va una entrada se toma en función de los últimos 4 bits solo de su código hash.
Aquí es donde entra en juego la multiplicación de cubos. Bajo ciertas condiciones (tomaría mucho tiempo explicarlo con detalles exactos ), los cubos se duplican en tamaño. ¿Por qué? Cuando los cubos se duplican en tamaño, entra en juego un bit más .
Entonces tiene 16 cubos: los últimos 4 bits del código hash deciden dónde va una entrada. Doblas los cubos: 32 cubos - 5 últimos bits deciden dónde irá la entrada.
Como tal, este proceso se llama rehacer. Esto podría volverse lento. Eso es (para las personas que se preocupan) como HashMap se "bromea" como: rápido, rápido, rápido, lento . Hay otras implementaciones: buscar hashmap sin pausa ...
Ahora UNTREEIFY_THRESHOLD entra en juego después de volver a aplicar el hash. En ese punto, algunas entradas pueden moverse de estos contenedores a otros (agregan un bit más al (n-1)&hash
cálculo y, como tal, pueden moverse a otros contenedores) y puede llegar a esto UNTREEIFY_THRESHOLD
. En este punto, no vale la pena mantener la papelera como red-black tree node
, sino como un LinkedList
lugar, como
entry.next.next....
MIN_TREEIFY_CAPACITY es la cantidad mínima de depósitos antes de que un determinado depósito se transforme en un árbol.
String
, tienen un espacio de valor mucho mayor que elint
código hash, por lo que las colisiones son inevitables. Ahora depende de los valores reales, como los valores realesString
, que pones en el mapa, ya sea que obtengas una distribución uniforme o no. Una mala distribución puede ser el resultado de una mala suerte.