기록방

Java Map의 computeIfAbsent(), computeIfPresent() 메서드 본문

CS/Java

Java Map의 computeIfAbsent(), computeIfPresent() 메서드

Soom_1n 2024. 5. 19. 00:41

java 8에서 추가된 Map 인터페이스의 디폴트 메서드로, key로 value를 검색하며 후처리를 진행하는 두 가지 메서드가 있습니다.

computeIfAbsent() 메서드는 key가 맵핑되어 있지 않을때,
computeIfPresent() 메서드는 key가 맵핑되어 있을 때 후처리를 진행합니다.

 

computeIfAbsent() 메서드

  • computeIfAbsent(key, mappingFunction)는 해당 key로 맵핑된 value가 있다면, value를 반환합니다.
  • 해당 key가 맵핑되지 않았다면, mappingFuncion을 실행합니다.

메서드 구현

default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
    Objects.requireNonNull(mappingFunction);
    V v;
    if ((v = get(key)) == null) {
        V newValue;
        if ((newValue = mappingFunction.apply(key)) != null) {
            put(key, newValue);
            return newValue;
        }
    }
    return v;
}

 

 

사용 예제

// ex1) 학생 성적 초기화
import java.util.HashMap;
import java.util.Map;

public class ComputeIfAbsentExample1 {
    public static void main(String[] args) {
        Map<String, Integer> studentGrades = new HashMap<>();
        studentGrades.put("Alice", 85);
        studentGrades.put("Bob", 92);

        // "Charlie" 학생이 없으면 성적을 75로 초기화
        studentGrades.computeIfAbsent("Charlie", key -> 75);

        // "Alice" 학생은 이미 있으므로 아무 작업도 하지 않음
        studentGrades.computeIfAbsent("Alice", key -> 90);

        System.out.println(studentGrades);
        // 출력: {Alice=85, Bob=92, Charlie=75}
    }
}


// ex2) 도서관 대출 기록 관리
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ComputeIfAbsentExample2 {
    public static void main(String[] args) {
        Map<String, Set<String>> libraryRecords = new HashMap<>();

        // "Harry Potter" 도서에 대해 새로운 대출 기록을 추가
        libraryRecords.computeIfAbsent("Harry Potter", key -> new HashSet<>()).add("John Doe");

        // "Lord of the Rings" 도서에 대해 새로운 대출 기록을 추가
        libraryRecords.computeIfAbsent("Lord of the Rings", key -> new HashSet<>()).add("Jane Smith");

        // "Harry Potter" 도서에 대해 또 다른 대출 기록을 추가
        libraryRecords.computeIfAbsent("Harry Potter", key -> new HashSet<>()).add("Emily Davis");

        System.out.println(libraryRecords);
        // 출력: {Harry Potter=[John Doe, Emily Davis], Lord of the Rings=[Jane Smith]}
    }
}

 

computeIfPresent() 메서드

  • computeIfPresent(key, mappingFunction)는 해당 key로 맵핑된 value가 있다면, 현재 value를 새롭게 맵핑하고 반환합니다.
  • 해당 key가 맵핑되지 않았다면, 현재 요청을 무시합니다.

메서드 구현

default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null) {
            put(key, newValue);
            return newValue;
        } else {
            remove(key);
            return null;
        }
    } else {
        return null;
    }
}

 

사용 예제

// ex1) 사용자 포인트 시스템 업데이트
import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresentExample1 {
    public static void main(String[] args) {
        Map<String, Integer> userPoints = new HashMap<>();
        userPoints.put("user1", 100);
        userPoints.put("user2", 150);

        // user1의 포인트를 50만큼 증가시키기
        userPoints.computeIfPresent("user1", (key, value) -> value + 50);

        // user3이 없으므로 아무 작업도 하지 않음
        userPoints.computeIfPresent("user3", (key, value) -> value + 50);

        System.out.println(userPoints);
        // 출력: {user1=150, user2=150}
    }
}

// ex2) 상품 재고 관리
import java.util.HashMap;
import java.util.Map;

public class ComputeIfPresentExample2 {
    public static void main(String[] args) {
        Map<String, Integer> productStock = new HashMap<>();
        productStock.put("apple", 50);
        productStock.put("banana", 30);

        // apple의 재고를 20만큼 감소시키기
        productStock.computeIfPresent("apple", (key, value) -> value - 20);

        // banana의 재고를 40만큼 감소시키기 (재고가 부족한 경우)
        productStock.computeIfPresent("banana", (key, value) -> (value - 40) < 0 ? null : value - 40);

        System.out.println(productStock);
        // 출력: {apple=30}
        // banana는 재고가 부족해서 삭제됨
    }
}
728x90

'CS > Java' 카테고리의 다른 글

자바 객체 직렬화 (serialization) 정리  (5) 2023.02.03