El JavaDoc de ConcurrentHashMapdice esto:
Me gusta
HashtableperoHashMapno me gusta , esta clase no permitenullser utilizada como clave o valor.
Mi pregunta: ¿por qué?
2da pregunta: ¿Por qué no Hashtablepermite nulo?
He usado muchos HashMaps para almacenar datos. Pero al cambiar a ConcurrentHashMapMe metí en problemas varias veces debido a NullPointerExceptions.
java
concurrenthashmap
Marcel
fuente
fuente

Respuestas:
Del autor de
ConcurrentHashMapsí mismo (Doug Lea) :fuente
Optionals como valores internamenteOptionales una característica de Java 8, que no estaba disponible en ese entonces (Java 5). Podrías usarOptionals ahora, de hecho.Creo que es, al menos en parte, para que pueda combinar
containsKeyygeten una sola llamada. Si el mapa puede contener nulos, no hay forma de saber sigetestá devolviendo un valor nulo porque no había una clave para ese valor, o simplemente porque el valor era nulo.¿Por que eso es un problema? Porque no hay una forma segura de hacerlo tú mismo. Toma el siguiente código:
Como
mes un mapa concurrente, la clave k puede eliminarse entre las llamadascontainsKeyyget, lo que hace que este fragmento devuelva un valor nulo que nunca estuvo en la tabla, en lugar de lo deseadoKeyNotPresentException.Normalmente lo resolverías sincronizando, pero con un mapa concurrente que, por supuesto, no funcionará. Por lo tanto, la firma de
gettuvo que cambiar, y la única forma de hacerlo de una manera compatible con versiones anteriores era evitar que el usuario inserte valores nulos en primer lugar, y continuar usándolo como un marcador de posición para "clave no encontrada".fuente
map.getOrDefault(key, NULL_MARKER). Si es asínull, el valor eranull. Si vuelveNULL_MARKER, el valor no estaba presente.Josh Bloch diseñado
HashMap; Doug Lea diseñadoConcurrentHashMap. Espero que eso no sea calumnioso. En realidad, creo que el problema es que los nulos a menudo requieren envoltura para que el nulo real pueda significar sin inicializar. Si el código del cliente requiere valores nulos, entonces puede pagar el costo (ciertamente pequeño) de envolver los valores nulos.fuente
No se puede sincronizar en un nulo.
Editar: Esto no es exactamente por qué en este caso. Inicialmente pensé que estaba ocurriendo algo interesante al bloquear cosas contra actualizaciones concurrentes o usar el monitor de objetos para detectar si algo se modificó, pero al examinar el código fuente parece que estaba equivocado: se bloquean usando un "segmento" basado en un máscara de bits del hash.
En ese caso, sospecho que lo hicieron para copiar Hashtable, y sospecho que Hashtable lo hizo porque en el mundo de la base de datos relacional, null! = Null, por lo que usar un nulo como clave no tiene sentido.
fuente
ConcurrentHashMap es seguro para subprocesos. Creo que no permitir claves y valores nulos fue parte de garantizar que sea seguro para subprocesos.
fuente
Supongo que el siguiente fragmento de la documentación de la API da una buena pista: "Esta clase es totalmente interoperable con Hashtable en programas que dependen de la seguridad de su hilo pero no de sus detalles de sincronización".
Probablemente solo querían hacer que sea
ConcurrentHashMaptotalmente compatible / intercambiableHashtable. Y comoHashtableno permite claves y valores nulos.fuente
No creo que rechazar el valor nulo sea una opción correcta. En muchos casos, queremos poner una clave con valor nulo en el mapa actual. Sin embargo, al usar ConcurrentHashMap, no podemos hacer eso. Sugiero que la próxima versión de JDK pueda soportar eso.
fuente