java - safe - ConcurrentHashMap putIfAbsent() devuelve un valor nulo
java map thread safe (7)
El siguiente programa está imprimiendo NULL. No puedo entender por qué.
public class ConcurrentHashMapTest {
public static final ConcurrentMap<String, String> map = new ConcurrentHashMap<>(5, 0.9f, 2);
public static void main(String[] args) {
map.putIfAbsent("key 1", "value 1");
map.putIfAbsent("key 2", "value 2");
String value = get("key 3");
System.out.println("value for key 3 --> " + value);
}
private static String get(final String key) {
return map.putIfAbsent(key, "value 3");
}
}
¿Podría alguien ayudarme a entender el comportamiento?
ConcurrentMap.putIfAbscent devuelve el valor anterior asociado con la clave especificada, o nulo si no hubo una asignación para la clave. No tenías un valor asociado con la "clave 3". Todo correcto
El problema es que, por definición, putIfAbsent devuelve el valor antiguo y no el nuevo (el valor antiguo de ausente siempre es nulo). Use computeIfAbsent : esto le devolverá un nuevo valor.
private static String get(final String key) {
return map.computeIfAbsent(key, s -> "value 3");
}
Está en el javadoc:
devuelve el valor anterior asociado con la clave especificada, o nulo si no hubo una asignación para la clave
Esta es una pregunta frecuente, que tal vez sugiera que este comportamiento no es intuitivo. Tal vez la confusión proviene de la forma en que dict.setdefault () funciona en python y otros idiomas. Devolver el mismo objeto que acaba de colocar ayuda a cortar algunas líneas de código.
Considerar:
if (map.contains(value)){
obj = map.get(key);
}
else{
obj = new Object();
}
versus:
obj = map.putIfAbsent(key, new Object());
Por favor, lea la documentación de ConcurrentHashMap.putIfAbsent
:
Devoluciones :
el valor anterior asociado con la clave especificada, onull
si no hubo asignación para la clave
Como no había ningún valor anterior para la clave "key 3"
, devuelve un null
.
Si nos fijamos en la documentación, dice:
Devoluciones:
el valor anterior asociado con la clave especificada, o nulo si no hubo asignación para la clave
En su caso, ningún valor se asoció previamente con la clave, por lo tanto NULL
putIfAbsent()
devuelve el valor anterior asociado con la clave especificada, o null
si no hubo una asignación para la clave, y porque la key 3
no está presente en el mapa, por lo que devuelve un null
.
Ha agregado la key 1
y la key 2
en el mapa, pero la key 3
no está asociada con ningún valor. Así que obtienes un null
. La key 3
mapa key 3
con algún valor y putIfAbsent()
devolverá el valor anterior asociado con esa clave.
Como si el mapa ya contuviera la key 3
asociada con el valor A
key 3 ---> A
Luego, al llamar a map.putIfAbsent("key 3","B")
devolverá A