Please enable JavaScript to view the comments powered by Disqus.Java map compute current value without if statement
Search
🪘

Java map compute current value without if statement

태그
Java
공개여부
작성일자
2022/10/10
최근에 코드리뷰를 하다가 편리한 기능을 공유하게 되어 간단하게 글로 남겨두면 좋겠다는 생각이 들어 작성하게 되었다. Map 에는 computeIfPresentputIfAbsent 라는 함수가 있다.
일단, 현재 코드는 다음과 같다.
protected Map<String, List<String>> separateMessageId(List<M> models) { Map<String, List<String>> messageIdentity = new HashMap<>(); for (M message : models) { if (messageIdentity.containsKey(message.getCwAppId())) { messageIdentity.get(message.getCwAppId()).add(message.getMessageId()); continue; } messageIdentity.put(message.getCwAppId(), new ArrayList() {{ add(message.getMessageId()); }}); } return messageIdentity; }
Java
복사
변경전 코드
로직은 다음과 같다.
1.
ID에 해당하는 key, value 가 map 에 있는지 확인한다.
2.
없으면 put(key, List<value>) 를 수행한다.
3.
있으면 value list에 현재 value 를 추가한다.
사실 크게 이상할 것은 없다.
하지만, 새로 추가된 함수를 다음과 같이 작성하면 더 편리해진다.
protected Map<String, List<String>> separateByCwAppId(List<M> models) { Map<String, List<String>> messagesByCwAppId = new HashMap<>(); for (M message : models) { messagesByCwAppId.computeIfPresent(message.getCwAppId(), (key, value) -> { value.add(message.getMessageId()); return value; }); messagesByCwAppId.putIfAbsent(message.getCwAppId(), new ArrayList() {{ add(message.getMessageId()); }}); } return messagesByCwAppId; }
Java
복사
변경한 코드
여기서 중요한 것은 computeIfPresentputIfAbsent 의 순서를 변경하면 안된다.
코드를 읽어보면 알겠지만, 없어서 key 와 list 를 put 하고, 다시 add 를 해주는 일이 생긴다.

computeIfPresent

JDK11 기준으로 computeIfPresent 의 함수는 아래와 같다.
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { Objects.requireNonNull(remappingFunction); V oldValue; if ((oldValue = get(key)) != null) { V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) { put(key, newValue); return newValue; } else { remove(key); return null; } } else { return null; } }
Java
복사
BiFunction 은 두개의 input을 받아 1개의 result 를 반환한다.
key 에 해당하는 value 가 없다면 함수는 null 을 반환한다.
key 에 해당하는 value 가 있다
새로운 value가 null이 아니면 새로운 value 를 put 하고, 새로운 value를 반환한다.
새로운 value가 null 이면, key, value 를 제거하고, null 을 반환한다.

putIfAbsent

JDK 11 기준으로 putIfAbsent 의 구현은 아래와 같다.
default V putIfAbsent(K key, V value) { V v = get(key); if (v == null) { v = put(key, value); } return v; }
Java
복사
무조건 value 를 반환한다.
Map에 저장된 key 가 없어야 동작한다.

주의할 점

default 구현은 모두 Map 안에 있는 구현이다.
따라서, thread-safe 같은 기능은 존재하지 않으므로 이러한 기능이 필요하다면 알맞은 구현체를 선택해야 한다.