Collectors.toMap NPE 주의

김민규·2023년 4월 4일
0

java

목록 보기
5/7
post-thumbnail

글의 코드는 java8 기준으로 작성했습니다.

문제발생

코드 리팩터링중에 기존 정책을 유지하기 위해 불가피하게 null을 다룰일이 생겼다.
그래서 value의 null을 허용하는 HashMap을 사용하는 도중 ❗NPE(NullPointException)가 발생했다.

아래 코드의 Collectors.toMap() 메서드에서 NPE가 발생한다.

HashMap<String, Object> hashMap1 = new HashMap<>();
hashMap1.put("a", 40_000L);
hashMap1.put("b", 30.1d);
hashMap1.put("c", null);

HashMap<String, Object> hashMap2 = new HashMap<>();
hashMap2.put("d", 40_000L);
hashMap2.put("e", 30.1d);
hashMap2.put("f", "hello");

Map<String, Object> mergedHashMap = Stream.of(hashMap1, hashMap2)
    .flatMap(map -> map.entrySet().stream())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

toMap() 메서드의 내부 구현 코드에는 아래와 같이 nonNull을 체크하는 로직이 존재하기 때문이다. 🚫

V v = Objects.requireNonNull(valueMapper.apply(element));

해결방법

toMap() 대신 Streamcollect 메서드를 그대로 활용한다.

<R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);
Map<String, Object> mergedHashMap = Stream.of(hashMap1, hashMap2)
    .flatMap(map -> map.entrySet().stream())
    .collect(HashMap::new, (map, entry) -> map.put(entry.getKey(), entry.getValue()), 
        HashMap::putAll);

mergedHashMap = {a=40000, b=30.1, c=null, d=40000, e=30.1, f=hello}

c key의 value null을 확인할 수 있다.

profile
Backend Engineer, Vim User

0개의 댓글