IT/JAVA

getOrDefault() vs computeIfAbsent()

iamhyeon 2025. 12. 6. 21:05

 

Java 컬렉션을 사용하다 보면 한 번쯤 마주치는 두 메서드가 있다.

  • getOrDefault(key, defaultValue)
  • computeIfAbsent(key, mappingFunction)

둘 다 “key가 없을 때 기본 값을 어떻게 처리할 것인가”라는 공통 목적을 가진 것처럼 보이지만,
작동 방식도 완전히 다르고, 쓰이는 상황도 전혀 다르다.

 

 

1. getOrDefault() — “단순 조회 + 기본 반환” 역할

V value = map.getOrDefault(key, defaultValue);

✔ 동작 방식

  • key가 존재하면 해당 value를 그대로 반환한다.
  • key가 존재하지 않으면 defaultValue를 반환만 한다.
  • Map 자체에는 아무 것도 추가되지 않는다.

✔ 특징

  • Map 수정 없음
  • 읽기(Read) 연산
  • defaultValue는 실제 Map에 넣지 않는다
  • 멀티스레드 환경에서 안전성 보장 ❌ (HashMap이라면 특히)

✔ 예시

Map<String, Integer> countMap = new HashMap<>();

int count = countMap.getOrDefault("apple", 0);
System.out.println(count); // 0 출력
System.out.println(countMap); // {} 그대로

✔ 언제 사용?

  • key가 없을 때 그냥 반환하기만 하면 되는 경우
  • Map을 수정하고 싶지 않은 경우
  • 단순 조회 + 기본 값 제공이 목적일 때

 

2. computeIfAbsent() — “없으면 생성하고 Map에 저장까지”

V value = map.computeIfAbsent(key, k -> new Value());

✔ 동작 방식

  • key가 이미 존재하면 value를 그대로 반환한다.
  • key가 존재하지 않으면 mappingFunction을 실행해 value를 생성하고 Map에 저장한 뒤 반환한다.

“조회 + 생성 + put”이 한 번에 이루어지는 원자적 연산이다.

✔ 특징

  • Map을 수정
  • 쓰기(Write) 연산
  • 기본 값은 Map에 저장된다
  • ConcurrentHashMap에서는 원자적으로 동작해서 멀티스레드 환경에서 안전

✔ 예시

ConcurrentHashMap<String, ReentrantLock> lockMap = new ConcurrentHashMap<>();

ReentrantLock lock = lockMap.computeIfAbsent("user1", k -> new ReentrantLock());
System.out.println(lockMap);
// {"user1"=ReentrantLock 객체} 저장됨

✔ 언제 사용?

  • key가 없으면 Map에 기본 객체를 생성해서 저장해야 할 때
  • 리소스 캐싱, 락 관리 등 객체가 여러 번 재사용되어야 할 때
  • 멀티스레드 환경에서 안전하게 “있는지 확인 → 없으면 생성”이 필요할 때
    (Double-checking 코드를 직접 만들 필요 X)

 

3. 두 메서드의 가장 큰 차이: Map을 수정하는지 

메서드 key가 없을 때 Map에 값 저장 멀티스레드 안전성
getOrDefault() defaultValue 그냥 반환 ❌ 저장 X Map 종류에 따라 unsafe
computeIfAbsent() 함수로 value 생성 + Map에 저장 ✔ 저장 O ✔ ConcurrentHashMap에서 thread-safe

 


 

getOrDefault()와 computeIfAbsent()는 비슷해 보이지만 목적이 완전히 다르다.

  • 조회 목적이면 getOrDefault
  • 객체 생성 + Map 저장이 필요하면 computeIfAbsent

특히 멀티스레드 환경에서 per-key 자원 관리가 필요하다면
computeIfAbsent()는 거의 필수라고 할 수 있다.

 

반응형

'IT > JAVA' 카테고리의 다른 글

Java 멀티스레드와 병렬 실행  (0) 2025.12.07
Java 함수형 인터페이스 Supplier, Runnable  (0) 2025.12.07
ReentrantLock 락 제어  (0) 2025.12.06
Java 예외: RuntimeException  (0) 2025.12.06
동기화 vs 원자적 연산  (1) 2025.07.24