Solución:
Diferencia # 1
computeIfAbsent
toma una función de mapeo, que se llama para obtener el valor si falta la clave.
putIfAbsent
toma el valor directamente.
Si el valor es caro de obtener, entonces putIfAbsent
desperdicia eso si la clave ya existe.
Un valor “caro” común es, por ejemplo, new ArrayList<>()
para cuando estás creando un Map<K, List<V>>
, donde la creación de una nueva lista cuando la clave ya existe (que luego descarta la nueva lista) genera basura innecesaria.
Diferencia # 2
computeIfAbsent
devuelve “el valor actual (existente o calculado) asociado con la clave especificada, o nulo si el valor calculado es nulo”.
putIfAbsent
devuelve “el valor anterior asociado con la clave especificada, o nulo si no había ningún mapeo para la clave”.
Entonces, si la clave ya existe, devuelven lo mismo, pero si falta la clave, computeIfAbsent
devuelve el valor calculado, mientras que putIfAbsent
devuelve nulo.
Diferencia # 3
Ambos métodos definen “ausente” como falta de clave o el valor existente es nulo, pero:
computeIfAbsent
no pondrá un valor nulo si la clave está ausente.
putIfAbsent
pondrá el valor si la clave está ausente, incluso si el valor es nulo.
No importa para futuras llamadas a computeIfAbsent
, putIfAbsent
, y get
llamadas, pero sí marca la diferencia en llamadas como getOrDefault
y containsKey
.
Suponga que tiene un Map<String,ValueClass>
.
map.putIfAbsent("key", new ValueClass());
creará un ValueClass
instancia de todos modos, incluso si la clave “clave” ya está en el Map
. Esto solo crearía una instancia innecesaria.
Por otra parte
map.computeIfAbsent("key", k -> new ValueClass());
solo creará un ValueClass
instancia si la clave “clave” no está ya en el Map
(o se asigna a un null
valor).
Por lo tanto computeIfAbsent
es más eficiente.
putIfAbsent
es equivalente a:
ValueClass value = new ValueClass();
if (map.get("key") == null) {
map.put("key",value);
}
tiempo computeIfAbsent
es equivalente a:
if (map.get("key") == null) {
map.put("key",new ValueClass());
}
Otra pequeña diferencia entre los dos métodos es que computeIfAbsent
no pondrá un null
valor para una clave ausente. putIfAbsent
voluntad.
Puede comprender la diferencia observando detenidamente las firmas del método:
-
putIfAbsent
toma una clave y un valor, y coloca el valor en el mapa si no hay ningún valor para esa clave en el mapa. -
computeIfAbsent
toma una llave y unFunction
. Si no hay ningún valor para esa clave en el mapa, se llama a la función para crear el valor, que luego se coloca en el mapa.
Si ya tiene el valor, use putIfAbsent
.
Si aún no tiene el valor y crearlo es una operación costosa (por ejemplo, el valor debe buscarse en una base de datos), utilice computeIfAbsent
, por lo que no es necesario realizar la costosa operación en caso de que el mapa ya contenga un valor para la clave especificada.