👉 computeIfAbsent
메서드
- computeIfAbsent는 Java의 Map 인터페이스에 정의된 메서드
- 주어진 Key에 대응하는 값이 Map에 없을 때만, 제공된 함수를 사용하여 새 값을 계산하고 Map에 추가함
- 이 메서드의 반환 타입은 Map의 값 타입에 의해 결정
👉 사용 방법과 특징
- 타입 일치
- Map의 값 타입이 반환 타입을 결정
- 예를 들어, Map<String, List>에서 computeIfAbsent는 List을 반환
- 참조 동작과 변경의 반영
- computeIfAbsent는 객체에 대한 참조를 반환
- 이 객체는 Map에 저장된 객체와 동일함
- 반환된 객체에 가해진 변경(예: 리스트에 요소 추가)은 Map에 저장된 해당 객체에도 반영됨
- 얕은 복사(shallow copy)와 유사
- Map의 참조 동작
- Java에서 Map의 값은 객체에 대한 참조로 저장됨
- 즉, Map에 객체를 저장할 때, 실제로 저장되는 것은 객체의 주소(참조)
- computeIfAbsent의 작동 원리
- computeIfAbsent 메서드는 키에 해당하는 값이 없을 때, 제공된 함수로부터 값을 생성하고, 이 값을 해당 키와 연결하여 Map에 저장
- 여기서 중요한 점은 Map에 저장되는 것이 객체의 참조라는 것
- 즉, Map 저장된 객체와 메서드에서 반환된 객체는 동일한 메모리 주소를 가리키는 하나의 객체
- 변경의 반영:
- computeIfAbsent로 반환된 객체(예: 리스트)에 변경을 가하면, 이 변경은 Map에 저장된 객체에도 반영됨
- 왜냐하면 둘은 실제로 동일한 객체(즉, 같은 메모리 주소를 가진 객체)이기 때문
- 따라서, 리스트에 요소를 추가하거나 수정하는 것은 Map에 저장된 해당 리스트에도 동일하게 적용됨
- 별도의 put 호출 없이도 Map에 저장된 객체가 업데이트됨
- 다운캐스팅의 필요성
- 일반적인 객체 타입(Object)을 사용하는 경우, computeIfAbsent의 반환값은 Object가 됨
- 특정 작업을 수행하기 위해서는 적절한 타입으로 명시적 다운캐스팅이 필요
👉 예시 코드
Map<String, Object> replyOrganize = new HashMap<>();
for (Map<String, Object> reply : replyList) {
String replyParentID = (String) reply.get("COMMENT_PARENT");
List<Map<String, Object>> replyListForParent = (List<Map<String, Object>>) replyOrganize.computeIfAbsent(replyParentID, k -> new ArrayList<>());
replyListForParent.add(reply);
}
- computeIfAbsent를 사용하여 각 replyParentID에 대한 List<Map<String, Object>>를 가져오거나 새로 생성하고, 그 리스트에 reply를 추가
- computeIfAbsent의 결과는 먼저 List<Map<String, Object>>로 캐스팅되고, 그 후에 add 메서드를 사용
- 변경 사항은 replyOrganize Map에 자동으로 반영됨
Map<String, Object> replyOrganize = new HashMap<>();
for (Map<String, Object> reply : replyList) {
String replyParentID = (String) reply.get("COMMENT_PARNET");
((List<Map<String, Object>>) replyOrganize.computeIfAbsent(replyParentID, k -> new ArrayList<>())).add(reply);
}