CodeGym /Blog Java /Random-ES /Método HashMap computeIfAbsent() en Java
Autor
Volodymyr Portianko
Java Engineer at Playtika

Método HashMap computeIfAbsent() en Java

Publicado en el grupo Random-ES
Java 8, como muchos de nosotros sabemos, introdujo Stream API. Este es un conjunto de herramientas muy útil, pero tiene un inconveniente, no incluye mapas . Sin embargo, Java 8 agregó varios métodos útiles a la propia interfaz de Map para reducir la cantidad de código "malo". Entonces, si necesita realizar alguna acción con el valor en Map , si existe en él, hay un método ComputeIfPresent() en Java Map. Si necesita hacer algo con un valor que no está en Map , puede usar el método ComputeIfAbsent() . Lo consideraremos en este artículo.

firma del método computeIfAbsent()


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
El método ComputeIfAbsent() de Map (y HashMap ) toma dos parámetros. El primer parámetro es la clave. El segundo parámetro es la función de mapeo . En este método, la función de mapeo solo se llama si no se presenta el mapeo.

Cómo funciona el método computeIfAbsent()

Como ya sabemos, al método Map.computeIfAbsent() se le pasan dos parámetros, la clave y la función para calcular el valor de esta clave mappingFunction . Aquí está el algoritmo lógico del método:
  1. El método primero verifica si la clave pasada está representada en nuestro Mapa .
  2. Si la clave está representada en Map (y no es nula), entonces el método no hace nada.
  3. De lo contrario, si la clave no se representa en Map (o es nula), el método calcula el valor usando la función de mapeo de la clave.
  4. Si el valor resultante no es nulo, escriba un par clave-valor para mapear.
Escribamos la misma lógica que el código:

if (map.get(key) == null) 
{ 
V newValue = mappingFunction.apply(key); 
if (newValue != null) map.put(key, newValue); 
}

ejemplo de código de computeIfAbsent()

Entonces, si el valor no está en el Mapa , entonces el método realizará los cambios. Veamos un ejemplo sencillo:

import java.util.HashMap;
import java.util.Map;

//map.computeIfAbsent example 
public class ComputeIfAbsentExample {

       public static void main(String[] args) {

           Map<String, String> myMap = new HashMap<>();

           myMap.computeIfAbsent("here is my key", key -> key + ", " + "and this is a new value");

           System.out.println(myMap.get("here is my key"));
       }
}
La salida es:
aquí está mi clave, y este es un nuevo valor
Ahora veamos qué hará el método cuando haya un valor dado en el Mapa . Alerta de spoiler: no hará nada.

import java.util.HashMap;
import java.util.Map;

public class ComputeIfAbsentExample2 {

       public static void main(String[] args) {

           Map<String, String> myMap = new HashMap<>();
           myMap.put("here is my key", "and here is my value");

           myMap.computeIfAbsent("here is my key", key -> key + ", " + "and this is a new value");

           System.out.println(myMap.get("here is my key"));
       }
}
Aquí está la salida:
y aquí está mi valor
Como puede ver, el valor permanece sin cambios.

Un ejemplo más de ComputeIfAbsent()

Si está familiarizado con el concepto de almacenamiento en caché, el método computeIfAbsent() probablemente le recuerde algo. Echemos un vistazo a un ejemplo de análisis más complejo. Llamemos al método computeIfAbsent() dos veces para asegurarnos de que en el primer caso el valor cambia, mientras que en el segundo no.

import java.util.HashMap;
import java.util.Map;

public class ComputeIfAbsentExample {
   private static Map<String, Long> numbersMap = new HashMap<>();

   public static Long stringToLong(String str) {
       return numbersMap.computeIfAbsent(str, key -> {
           System.out.println("parsing: " + key);
           return Long.parseLong(key);
       });
   }

   public static void main(String[] args) {
       // will print:
       // > parsing: 10
       // > parsing: 25
       // > 10+25=35
       System.out.println("10+25=" + (stringToLong("10") + stringToLong("25")));
       // will print:
       // > parsing: 20
       // > 10+25=45
       // only "20" will be parsed this time, since "25" was already parsed and placed into `numbersMap` map before
       System.out.println("20+25=" + (stringToLong("20") + stringToLong("25")));
       // will print:
       // > 10+20=30
       // no parsing will occur, since both "10" and "20" were already parsed and placed into `numbersMap` map before
       System.out.println("10+20=" + (stringToLong("10") + stringToLong("20")));
   }

}
Aquí está la salida:
análisis: 25 10+25=35 análisis: 20 20+25=45 10+20=30
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION