CodeGym /Blogue Java /Random-PT /HashMap computeIfAbsent () método em Java
John Squirrels
Nível 41
San Francisco

HashMap computeIfAbsent () método em Java

Publicado no grupo Random-PT
O Java 8, como muitos de nós sabemos, introduziu a API Stream. Este é um kit de ferramentas muito útil, mas tem uma desvantagem: não inclui mapas . No entanto, o Java 8 adicionou vários métodos úteis à própria interface Map para reduzir a quantidade de código "ruim". Então, caso precise realizar alguma ação com o valor no Map , caso exista nele, existe um método ComputeIfPresent() no Java Map. Se precisar fazer algo com um valor que não esteja em Map , você pode usar o método ComputeIfAbsent() . Vamos considerá-lo neste artigo.

assinatura do método computeIfAbsent()


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
O método map (e HashMap ) computeIfAbsent() usa dois parâmetros. O primeiro parâmetro é a chave. O segundo parâmetro é o mappingFunction . Neste método a função de mapeamento só é chamada se o mapeamento não for apresentado.

Como funciona o método computeIfAbsent()

Como já sabemos, o método Map.computeIfAbsent() recebe dois parâmetros, a chave e a função para calcular o valor dessa chave mappingFunction . Aqui está o algoritmo lógico do método:
  1. O método primeiro verifica se a chave passada está representada em nosso Map .
  2. Se a chave estiver representada em Map (e não for nula), o método não fará nada.
  3. Caso contrário, se a chave não representar no mapa (ou for nula), o método calcula o valor usando mappingFunction para a chave.
  4. Se o valor resultante não for nulo, grave um par chave-valor no mapa.
Vamos escrever a mesma lógica do código:

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

exemplo de código computeIfAbsent()

Então, se o valor não estiver no Map , então o método fará as alterações. Vejamos um exemplo simples:

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"));
       }
}
A saída é:
aqui está minha chave, e este é um novo valor
Agora vamos ver o que o método fará quando houver um determinado valor no Map . Alerta de spoiler: não fará 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"));
       }
}
Aqui está a saída:
e aqui está o meu valor
Como você pode ver, o valor permanece inalterado.

Mais um exemplo de ComputeIfAbsent()

Se você estiver familiarizado com o conceito de armazenamento em cache, o método computeIfAbsent() provavelmente o lembrará de algo. Vamos dar uma olhada em um exemplo de análise mais complexo. Vamos chamar o método computeIfAbsent() duas vezes para garantir que no primeiro caso o valor mude, enquanto no segundo não.

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")));
   }

}
Aqui está a saída:
análise: 10 análise: 25 10+25=35 análise: 20 20+25=45 10+20=30
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION