글의 코드는 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()
대신 Stream
의 collect
메서드를 그대로 활용한다.
<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
을 확인할 수 있다.