많은 사람들이 알고 있듯이 Java 8은 Stream API를 도입했습니다. 이것은 매우 유용한 툴킷이지만 Map 을 포함하지 않는다는 단점이 있습니다 . 그러나 Java 8은 "잘못된" 코드의 양을 줄이기 위해 Map 인터페이스 자체에 몇 가지 유용한 메서드를 추가했습니다. 따라서 Map 에 있는 값으로 어떤 작업을 수행해야 하는 경우 Java Map에 ComputeIfPresent() 메서드 가 있습니다 . Map 에 없는 값으로 작업을 수행해야 하는 경우 ComputeIfAbsent() 메서드를 사용할 수 있습니다 . 이 기사에서 고려할 것입니다.

computeIfAbsent() 메서드 서명


default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
Map (및 HashMap ) computeIfAbsent () 메서드는 두 개의 매개변수를 사용합니다. 첫 번째 매개변수는 키입니다. 두 번째 매개변수는 mappingFunction 입니다 . 이 메서드에서 매핑 함수는 매핑이 표시되지 않은 경우에만 호출됩니다.

computeIfAbsent() 메서드 작동 방식

이미 알고 있듯이 Map.computeIfAbsent() 메서드에는 키와 이 키 mappingFunction 값을 계산하는 함수라는 두 개의 매개 변수가 전달됩니다 . 방법의 논리적 알고리즘은 다음과 같습니다.
  1. 메서드는 먼저 전달된 키가 Map 에 표시되는지 확인합니다 .
  2. 키가 Map 에 표시되고 null이 아닌 경우 메서드는 아무 작업도 수행하지 않습니다.
  3. 키가 Map 에 표시되지 않거나 (또는 null인 경우) 메서드는 키에 대한 mappingFunction을 사용하여 값을 계산합니다.
  4. 결과 값이 null이 아닌 경우 키-값 쌍을 매핑에 씁니다.
코드와 동일한 논리를 작성해 보겠습니다.

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

computeIfAbsent() 코드 예제

따라서 값이 Map 에 없으면 메서드가 변경을 수행합니다. 간단한 예를 살펴보겠습니다.

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"));
       }
}
출력은 다음과 같습니다.
여기 내 열쇠가 있고 이것은 새로운 가치입니다
이제 Map 에 주어진 값이 있을 때 메소드가 무엇을 하는지 봅시다 . 스포일러 경고: 아무것도 하지 않습니다.

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"));
       }
}
결과는 다음과 같습니다.
그리고 여기 내 가치가 있습니다
보시다시피 값은 변경되지 않습니다.

하나 더 ComputeIfAbsent() 예제

캐싱 개념에 익숙하다면 computeIfAbsent() 메서드가 뭔가를 떠올리게 할 것입니다. 좀 더 복잡한 구문 분석 예제를 살펴보겠습니다. computeIfAbsent() 메서드를 두 번 호출하여 첫 ​​번째 경우에는 값이 변경되고 두 번째 경우에는 변경되지 않도록 합시다.

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

}
결과는 다음과 같습니다.
파싱: 10 파싱: 25 10+25=35 파싱: 20 20+25=45 10+20=30