Map 인터페이스에서 Java 8 버전에 추가된 여러 API에 대해 설명합니다.
- putIfAbsent()
- compute()
- computeIfPresent()
- computeIfAbsent()
- getOrDefault()
그 코드는 Map 인터페이스의 구현 체인입니다.
HashMap를 기준으로 정리했습니다.
1. putIfAbsent(K key, V value)
putIfAbsent() 메소드는 네이밍으로부터 추측할 수 있도록(듯이), 다음과 같이 동작합니다.
- 키가 존재하는 경우: Value 변경 없이 기존에 존재하는 Key 의 Value 를 돌려준다합니다.
- 키가 없는 경우: Key 에 대응하는 Value 를 저장한 후에 null 를 돌려준다합니다.
Map 구현인 HashMap을 보면 putVal() 메서드를 통해 진행하고, Key 가 존재하는 경우는 oldValue 를 돌려주고, 그렇지 않은 경우는 null 를 돌려줍니다.
- map에 key=20, value=5의 데이터를 put합니다.
- map.putIfAbsent(20, 10): Key 가 존재하기 때문에, Value 의 변경 없이 5 를 돌려줍니다.
- map.putIfAbsent(10, 5): Key 가 존재하지 않기 때문에, 5 를 보존해 null 를 돌려줍니다.
2. compute(K key, BiFunction super K, ? super V, ? extends V> remappingFunction)
compute() 메서드는 다음과 같이 작동합니다.
- 키의 유무에 관계없이 전달된 인수를 통해 람다 함수를 적용하고 결과에 따라 키를 삭제하거나 새 값을 저장합니다.
- 키가 없는 경우 NullPointerException 가 발생할 가능성이 있습니다.
위의 8 행에 존재하지 않는 Key에 대해서는 NullPointerException 예외가 발생합니다.
null 상태로 intValue() 메소드를 호출하려고 하면 NPE 에러가 발생한다합니다.
따라서 위의 경우 함수 연산을 수행하기 전에 value 값을 확인하고 설정하면 예외가 발생하지 않습니다.
3. computeIfAbsent(K key, Function super K, ? extends V> mappingFunction
computeIfAbsent() 메서드는 다음과 같이 작동합니다.
- 키가 존재하는 경우: 아무것도하지 않고 기존에 존재하는 키의 값을 반환합니다.
- 키가 없는 경우: 람다 식을 적용한 값을 해당 키에 저장하고 newValue를 반환합니다.
computeIfAbsent() 메서드는 위에서 본 putIfAbsent() 메서드와 마찬가지로 작동합니다.
Key가 존재하는 경우는 기존의 Value를 돌려주고, Key가 존재하지 않는 경우는 새로운 값을 보존하고 나서 null를 돌려줍니다 (putIfAbsent), 또는 새로운 값 (newValue, computeIfAbsent ()를 돌려주는 차이만) 합니다.
4. computeIfPresent(K key, Function super K, ? extends V> mappingFunction
computeIfPresent() 메서드는 다음과 같이 작동합니다.
- 키가 존재하는 경우: 람다 식을 적용한 값이 null이 아닌 경우는 그 키에 저장하고 나서 돌려줍니다.
null의 경우는 키를 삭제해 null를 돌려줍니다. - 키가 없는 경우: null 반환
computeIfPresent() 예제
상기의 코드는, key 의 value 가 1 이면 key 를 삭제해, 1 이 아닌 경우 (1 보다 큰 경우) -1 를 실시하는 단순한 로직입니다.
after 코드에서 value가 1이면 람다 식의 결과 값을 null로 설정하고, 1이 아닌 경우 기존 value – 1합니다.
(위 computeIfPresent() 방법에서 람다 식의 결과 값이 null이면 키 삭제한 후 null을 반환하기 때문입니다.
)
5. getOrDefault(Object key, V defaultValue)
getOrDefault() 메서드는 다음과 같이 작동합니다.
- key가 존재하는 경우: key 에 존재하는 value 를 돌려준다합니다.
- 키가 없는 경우: 두 번째 인수로 설정 defaultValue 반환합니다.
getOrDefault() 메소드를 사용하면(자), 코드가 간결하게 되어, 가독성이 향상하기 위해, 개인적으로 자주 사용되는 메소드의 1 개입니다.
getOrDefault() 메소드를 사용하지 않는 경우는, before 코드와 같이 Map 에 key 가 매회 존재할지 어떨지를 확인할 필요가 있습니다.
그러나, getOrDefault() 메소드는, key가 존재하지 않는 경우는 defaultValue를 지정할 수 있기 때문에, 매우 편리하게 사용할 수 있습니다.