CodeGym /Blog Java /Random-PL /Metoda HashMap computeIfAbsent() w Javie
Autor
Volodymyr Portianko
Java Engineer at Playtika

Metoda HashMap computeIfAbsent() w Javie

Opublikowano w grupie Random-PL
Jak wielu z nas wie, Java 8 wprowadziła Stream API. Jest to bardzo przydatny zestaw narzędzi, ale ma wadę, nie zawiera Map s. Jednak Java 8 dodała kilka przydatnych metod do samego interfejsu Map , aby zmniejszyć ilość „złego” kodu. Tak więc, jeśli musisz wykonać jakąś akcję z wartością w Map , jeśli w niej istnieje, istnieje metoda ComputeIfPresent() w Java Map. Jeśli musisz zrobić coś z wartością, której nie ma w Map , możesz użyć metody ComputeIfAbsent() . Rozważymy to w tym artykule.

sygnatura metody computeIfAbsent().


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
Metoda Map (i HashMap ) computeIfAbsent () przyjmuje dwa parametry. Pierwszym parametrem jest klucz. Drugim parametrem jest mappingFunction . W tej metodzie funkcja mapowania jest wywoływana tylko wtedy, gdy mapowanie nie jest prezentowane.

Jak działa metoda computeIfAbsent().

Jak już wiemy, metodzie Map.computeIfAbsent() przekazywane są dwa parametry, klucz i funkcja obliczania wartości dla tego klucza mappingFunction . Oto logiczny algorytm metody:
  1. Metoda najpierw sprawdza, czy przekazany klucz jest reprezentowany w naszej Map .
  2. Jeśli klucz jest reprezentowany w Map (i nie jest pusty), metoda nic nie robi.
  3. W przeciwnym razie, jeśli klucz nie reprezentuje w Mapie (lub jest pusty), metoda oblicza wartość przy użyciu mappingFunction do klucza.
  4. Jeśli wynikowa wartość nie jest pusta, zapisz parę klucz-wartość do mapowania.
Napiszmy tę samą logikę co kod:

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

przykład kodu computeIfAbsent().

Tak więc, jeśli wartości nie ma w Map , metoda wykona zmiany. Spójrzmy na prosty przykład:

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"));
       }
}
Dane wyjściowe to:
oto mój klucz, a to jest nowa wartość
Zobaczmy teraz, co zrobi metoda, gdy w Mapie znajdzie się dana wartość . Alert spoilera: to nic nie da.

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"));
       }
}
Oto dane wyjściowe:
i tu jest moja wartość
Jak widać, wartość pozostaje niezmieniona.

Jeszcze jeden przykład ComputeIfAbsent().

Jeśli znasz koncepcję buforowania, metoda computeIfAbsent() prawdopodobnie coś ci przypomina. Rzućmy okiem na bardziej złożony przykład analizy składniowej. Wywołajmy metodę computeIfAbsent() dwukrotnie, aby upewnić się, że w pierwszym przypadku wartość się zmieni, aw drugim nie.

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

}
Oto dane wyjściowe:
analizowanie: 10 analizowanie: 25 10+25=35 analizowanie: 20 20+25=45 10+20=30
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION