¿Cuáles son las colecciones comunes?
A: La Map
interfaz y la Collection
interfaz es la interfaz padre de toda marco de las colecciones:
Collection
interfaz Subinterfaz comprende:List
una interfaz ySet
una interfaz;List
clase de implementación de la interfazArrayList
son:LinkedList
,,Stack
yVector
similares;Set
clase de implementación de la interfazHashSet
son:TreeSet
,,LinkedHashSet
y similares;
Map
clase de implementación de la interfazHashMap
son:TreeMap
,Hashtable
,,ConcurrentHashMap
yProperties
similares;
HashMap
Y Hashtable
la diferencia?
-
HashMap
No considerar la sincronización es insegura para subprocesos; elHashtable
uso desynchronized
palabras clave es seguro para subprocesos; -
HashMap
PermitirK/V
sonnull
, este últimoK/V
no pueden anull
; -
HashMap
Heredar deAbstractMap
clase yHashtable
heredar deDictionary
clase;
HashMap
¿Por qué no usar directamente el hashCode()
valor hash procesado como table
subíndice?
Respuesta: El hashCode()
método devuelve un tipo entero de int, que tiene un rango de -(2^31)~(2^31 - 1)
aproximadamente 4 mil millones de espacios de mapeo. La HashMap
capacidad está en el intervalo 16
(por defecto inicialización) ~2^30
, el HashMap es usualmente menor que el valor máximo tomado, y el dispositivo también es difícil proporcionar tanto espacio de almacenamiento, haciendo que hashCode()
el valor de hash calculado de la gama de tamaño de la matriz puede no ser Dentro, y por lo tanto no puede coincidir con la ubicación de almacenamiento.
Entrevistador: ¿Cómo resolverlo?
Respuesta: HashMap
He implementado mi propio hash()
método: a través de dos perturbaciones, hace que su propio valor de hash sea alto o bajo para realizar la operación XOR por sí mismo, lo que reduce la probabilidad de colisión de hash y hace que la distribución de datos sea más uniforme.
Cuando se garantiza que la longitud de la matriz es una potencia de 2, use hash()
el valor después de la operación y la operación ( &
) ( 数组长度 - 1
) para obtener el subíndice de la matriz para el almacenamiento:
- Primero, es más eficiente que tomar la operación de descanso;
- La segunda razón es que
h&(length-1)
solo es equivalente a cuando la longitud de la matriz es una potencia de dosh%length
; - Tres para resolver el problema "el valor hash no coincide con el tamaño de la matriz".
Entrevistador: ¿Por qué se garantiza que la longitud de la matriz sea una potencia de 2?
Respuesta: Solo cuando la longitud de la matriz es una potencia de 2, h&(length - 1)
es equivalente al posicionamiento h%length
alcanzado key
. La potencia de 2 también puede reducir el número de conflictos y mejorar la HashMap
eficiencia de la consulta.
Si length
una potencia de dos se length - 1
convierte a binario debe ser 11111……
en la forma, en el que h
la eficiencia de operación binaria es muy rápido, y el espacio no se desperdicia, y si length
la energía no es 2, por ejemplo length
es de 15, length - 1
14, correspondiente al sistema binario 1110
, que h
la operación, el último son 0
, y 0001
, 0011
, 0101
, 1001
, 1011
, 0111
, 1101
esta posición no se almacenará varios elementos, y un considerable desperdicio de espacio, o peor aún, este es el caso, la posición de la matriz se puede utilizar de matrices La longitud es mucho menor, lo que significa que la probabilidad de colisión aumenta aún más y la eficiencia de la consulta se ralentiza. Esto causará una pérdida de espacio.
Entrevistador: ¿Por qué hay dos disturbios?
Respuesta: Esto es para aumentar la aleatoriedad del orden bajo del valor hash, de modo que la distribución sea más uniforme, mejorando así la &
uniformidad de aleatoriedad de la posición del índice de almacenamiento de matriz correspondiente y, en última instancia, reduciendo el Hash
conflicto. Dos veces es suficiente. El propósito de la operación.
HashMap
¿Cómo es diferente en JDK 1.7
y JDK 1.8
?
Diferente | JDK 1.7 | JDK 1.8 |
---|---|---|
Estructura de almacenamiento | Matriz + lista vinculada | Matriz + lista vinculada + árbol rojo negro |
Método de inicialización | Función separada:inflateTable() |
Integrados directamente en la función de expansión resize() en |
Método de cálculo del valor hash | Procesamiento de perturbaciones = 9 perturbaciones = operaciones de 4 bits + 5 operaciones XOR | Procesamiento de perturbaciones = 2 perturbaciones = operación de 1 bit + 1 operación XOR |
Reglas para almacenar datos | Cuando no haya conflicto, almacene la matriz; cuando haya conflicto, almacene la lista vinculada | Cuando no haya conflicto, almacene la matriz; conflicto y longitud de la lista vinculada <8: almacene una sola lista vinculada; conflicto y longitud de la lista vinculada> 8: árbol y almacene el árbol rojo-negro |
Insertar datos | Método de interpolación de cabezales (primero hable sobre la posición original de los datos movidos al último, y luego inserte los datos en la posición) | Método de inserción de cola (inserción directa en la cola de la lista vinculada / árbol rojo-negro) |
Método de cálculo de la ubicación de almacenamiento después de la expansión de la capacidad. | Todos los cálculos se realizan de acuerdo con el método original (es decir, hashCode - >> función de perturbación - >> (h&length-1) ) |
Calcular de acuerdo con la ley después de la expansión de la capacidad (es decir, la ubicación después de la expansión de la capacidad = ubicación original o ubicación original + capacidad anterior) |
¿Por qué es adecuado el HashMap
medio String
y el Integer
embalaje K
?
Respuesta: Las características del embalaje String
, Integer
como por ejemplo, pueden garantizar Hash
el valor inmutable y la precisión del cálculo del valor, y pueden reducir efectivamente Hash
la probabilidad de colisión.
- Todos son
final
tipos, es decir, inmutabilidad e inmutabilidad garantizada,key
y no habráhash
casos en que los valores obtenidos sean diferentes; - Los métodos internos se han reescrito
equals()
,hashCode()
etc. , y se han seguidoHashMap
las especificaciones internas (no está claroputValue
sobre el proceso que puede ver arriba ), y no es propenso aHash
errores de cálculo de valores;
Entrevistador: ¿Qué pasa si quiero hacer mi propia Object
como K
¿cómo debo hacerlo?
Respuesta: reescribir hashCode()
y equals()
método.
-
La reescritura
hashCode()
se debe a que se debe calcular la ubicación de almacenamiento de los datos almacenados, y se debe tener cuidado de no tratar de excluir la parte clave de un objeto del cálculo del código hash para mejorar el rendimiento, que puede ser más rápido pero puede causar másHash
colisiones; -
El
equals()
método de reescritura debe cumplir con la reflexividad, la simetría, la transitividad, la coherencia y cualquiernull
valor que no sea de referenciax
, estosx.equals(null)
deben devolversefalse
, el propósito es garantizarkey
la unicidad en la tabla hash;
Mecanismo de falla rápida de la colección Java " fail-fast
"?
A: El mecanismo de detección de error es un conjunto de Java cuando múltiples hilos en el conjunto de cambios estructurales durante la operación, es probable que cause fail-fast
mecanismo.
Por ejemplo: suponga que hay dos hilos (hilo 1, hilo 2), el hilo 1 Iterator
atraviesa los elementos de la colección A, en algún momento el hilo 2 modificó la estructura de la colección A (es una modificación estructural, no una simple modificación una colección de elementos de contenido), así que esta vez el programa arrojará ConcurrentModificationException
una excepción, la producción de fail-fast
mecanismos.
La razón: iterador acceder al contenido de la colección directamente cuando se atraviesa y atravesando mediante un proceso modCount
variable. Si el contenido se produce el cambio es atravesada durante la recolección, que va a cambiar modCount
el valor. Cada vez que el iterador utilizando hashNext()/next()
el siguiente antes de un elemento transversal detectará modCount
si una variable es expectedmodCount
el valor, que se devuelve después de atravesar, de lo contrario se produce una excepción, terminar el recorrido.
Solución:
-
En el proceso de recorrido, todos ellos relacionados con el cambio de
modCount
lugar que vale la pena todos juntossynchronized
. -
Utilizar
CopyOnWriteArrayList
para sustituirArrayList
;
ArrayList
Y Vector
la diferencia?
A: Las dos clases implementan List
interfaces ( List
interfaces de heredados Collection
interfaces), que están conjunto ordenado, que la posición de elemento se almacena en estos dos conjuntos son secuenciales, el equivalente de una matriz dinámica, nos después de la posición de índice puede ser eliminado por un elemento, y en el que los datos se dejó repetición, que es HashSet
las diferencias máximas y similares set, HashSet
colección o similar no puede ser identificado por el número de índice para recuperar los elementos en el mismo, no está permitido Hay elementos que se repiten.
ArrayList
Y Vector
la diferencia entre los dos aspectos principales:
-
Sincronización :
Vector
es thread-safe, que se encuentra entre su método de sincronización de subprocesos (además desynchronized
la clave), yArrayList
es seguro de rosca, entre las que el método es de sincronización hilo. Si solo un hilo accede a la colección, es mejor usarloArrayList
, ya que no considera el problema de la seguridad del hilo, por lo que la eficiencia será mayor; si varios hilos acceden a la colección, es mejor usarloVector
, porque no nos necesita Piense y escriba un código seguro para subprocesos usted mismo. -
El crecimiento de datos:
ArrayList
yVector
tiene un tamaño de capacidad inicial, cuando el almacenamiento en el interior del mismo el número de elementos es superior a la necesidad de capacidad aumentaArrayList
yVector
espacio de almacenamiento, cada espacio de memoria para aumentar, no sólo una célula aumenta de memoria, En cambio, se agregan varias unidades de almacenamiento, y la cantidad de unidades de almacenamiento agregadas cada vez es un cierto equilibrio entre la utilización del espacio de memoria y la eficiencia del programa.Vector
Los datos está llena (factor de carga 1) el crecimiento se duplicó (expansión incremental: 2 veces el volumen original), yArrayList
cuando la cantidad de datos llega a la mitad de la capacidad de crecimiento (factor de carga 0.5) del volumen original (0,5 veces + 1) espacios.
ArrayList
Y LinkedList
la diferencia?
A: LinkedList
implementos List
y Deque
las interfaces, comúnmente conocida como una lista doblemente enlazada; ArrayList
implementos List
una interfaz, matrices dinámicas;
LinkedList
Una mayor eficiencia al insertar y borrar datosArrayList
en la búsqueda de unaindex
mayor eficiencia de los datos;LinkedList
RelaciónArrayList
requiere más memoria;
Array
Y ArrayList
¿cuál es la diferencia? Cuando ser Array
y no ArrayList
hacer?
Respuesta: La diferencia es:
Array
Puede contener tipos básicos y tipos de objetos,ArrayList
solo tipos de objetos.Array
El tamaño es fijo yArrayList
el tamaño cambia dinámicamente.ArrayList
Ofrece más métodos y propiedades, talesaddAll()
como:removeAll()
,,iterator()
y así sucesivamente.
Para los tipos básicos de datos, las colecciones usan agrupamiento automático para reducir la carga de trabajo de codificación. Sin embargo, este enfoque es relativamente lento cuando se trata con tipos de datos básicos de tamaño fijo.
HashSet
¿Cómo garantizar que los datos no sean repetibles?
R: HashSet
La capa inferior es en realidad HashMap
, es solo que HashSet
implementamos la Set
interfaz y usamos los datos como el K
valor, y el V
valor se ha guardado con el mismo valor ficticio . Podemos ver el código fuente:
public boolean add(E e) {
// 调用HashMap的put方法,PRESENT是一个至始至终都相同的虚值
return map.put(e, PRESENT)==null;
}
Debido a que HashMap
el K
valor en sí mismo no se permite repetir, y HashMap
si el valor K/V
es el mismo en el medio , el V
antiguo se sobrescribirá con el nuevo V
, y luego se devolverá el antiguo V
. Luego, HashSet
ejecutar esta oración en el siempre devolverá uno false
, causando que la inserción falle, lo que garantiza La no repetibilidad de los datos.