Collectors toMap 사용 시 Duplicate key 오류

joona95·2025년 1월 28일

평소에 List 에서 Map 으로 변경하고 싶을 때 Stream 에서 Collectors.toMap() 을 주로 사용하는 편이었다. 이 방법이 가독성도 좋고 간단해서 사용하기 편했던 것이 이유였다.

하지만 메서드를 사용할 때 어떻게 기능을 하는지 제대로 파악하지 못하고 사용하면 큰 문제가 발생할 수 있다는 걸 경험하게 됐다. 이 일을 계기로 코드를 작성할 때 조금 더 방어적으로 작성할 필요성을 많이 느꼈다. 또한 메서드를 사용할 때 어떤 식으로 작동하는 지에 대해서도 정확히 알고 사용할 필요성에 대해서도 많이 느꼈다.

문제 상황

// 예시 코드
Map<String, String> map = list.stream().collect(Collectors.toMap(A::getId, A::getName));

Collectors.toMap() 설명을 보면 중복키가 발생하는 경우 Duplicate key 예외가 발생한다고 한다.

DB 자체에서는 PK 나 Unique 설정이 되어 있지 않았는데 나는 당연하게 중복키 발생이 되지 않을 거라고 생각을 했었는데 내부적으로 중복키가 발생할 수 있는 구조였고, toMap 이 어떤 식으로 동작하는지 제대로 알지 못한 채 사용해서 문제가 발생했었다.

해결 방안

  1. containsKey 사용
Map<String, String> map = new HashMap();
for(A a : list) {
	if(!map.containsKey(a.getId())) {
    	map.put(a.getId(), a.getName());
    }
}
  1. toMap(Function, Function, BinaryOperator) 사용
Map<String, String> map = list.stream().collect(Collectors.toMap(A::getId, A::getName, (o1, o2) -> o1));
  • 먼저 오는 값 적용하고 싶을 때 : (o1, o2) -> o1
  • 나중에 오는 값 적용하고 싶을 때 : (o1, o2) -> o2

0개의 댓글