CodeGym /Java Blog /Random-IT /Metodo HashMap computeIfAbsent() in Java
John Squirrels
Livello 41
San Francisco

Metodo HashMap computeIfAbsent() in Java

Pubblicato nel gruppo Random-IT
Java 8, come molti di noi sanno, ha introdotto l'API Stream. Questo è un toolkit molto utile, ma ha uno svantaggio, non include Map s. Tuttavia, Java 8 ha aggiunto diversi metodi utili all'interfaccia Map stessa per ridurre la quantità di codice "cattivo". Quindi, se è necessario eseguire un'azione con il valore in Map , se esiste in esso, esiste un metodo ComputeIfPresent() in Java Map. Se devi fare qualcosa con un valore che non è in Map , puoi usare il metodo ComputeIfAbsent() . Lo considereremo in questo articolo.

firma del metodo computeIfAbsent()


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
Il metodo Map (e HashMap ) computeIfAbsent() accetta due parametri. Il primo parametro è la chiave. Il secondo parametro è la mappingFunction . In questo metodo la funzione di mappatura viene chiamata solo se la mappatura non viene presentata.

Come funziona il metodo computeIfAbsent()

Come già sappiamo, al metodo Map.computeIfAbsent() vengono passati due parametri, la chiave e la funzione per calcolare il valore di questa chiave mappingFunction . Ecco l'algoritmo logico del metodo:
  1. Il metodo controlla innanzitutto se la chiave passata è rappresentata nel nostro Map .
  2. Se la chiave è rappresentata in Map (e non è nulla), il metodo non fa nulla.
  3. Altrimenti se la chiave non rappresenta in Map (o è nulla) il metodo calcola il valore usando mappingFunction alla chiave.
  4. Se il valore risultante non è nullo, scrivi una coppia chiave-valore da mappare.
Scriviamo la stessa logica del codice:

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

esempio di codice computeIfAbsent()

Quindi, se il valore non è in Map , il metodo eseguirà le modifiche. Diamo un'occhiata a un semplice esempio:

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"));
       }
}
L'uscita è:
ecco la mia chiave, e questo è un nuovo valore
Ora vediamo cosa farà il metodo quando c'è un dato valore in Map . Avviso spoiler: non farà nulla.

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"));
       }
}
Ecco l'output:
ed ecco il mio valore
Come puoi vedere, il valore rimane invariato.

Un altro esempio ComputeIfAbsent()

Se hai familiarità con il concetto di memorizzazione nella cache, il metodo computeIfAbsent() probabilmente ti ricorda qualcosa. Diamo un'occhiata a un esempio di parsing più complesso. Chiamiamo due volte il metodo computeIfAbsent() per assicurarci che nel primo caso il valore cambi, mentre nel secondo 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")));
   }

}
Ecco l'output:
analisi: 10 analisi: 25 10+25=35 analisi: 20 20+25=45 10+20=30
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION