Junit을 이용해 자바8부터 추가된 HashMap의 메서드를 더 간결하고 효율적으로 사용하는 방법을 익히고자 작성한 테스트 코드입니다.
package map;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.HashMap;
import java.util.Map;
class Test {
// 자바8 HashMap 보다 간결하고 효과적으로 작성하기
// https://blog.advenoh.pe.kr/java/%EC%9E%90%EB%B0%948-HashMap-%EB%B3%B4%EB%8B%A4-%EA%B0%84%EA%B2%B0%ED%95%98%EA%B3%A0-%ED%9A%A8%EA%B3%BC%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0/
// https://rian-yeji.github.io/algorithm/2019/07/09/algorithm-hashmap-basic.html
/*
* default V putIfAbsent(K key, V value);
*
* - key: Map의 key 값
* - value: value 값
* - 반환값:
* - key값이 존재하는 경우 Map의 value값을 반환한다.
* - key값이 존재하지 않는 경우 key와 value를 Map에 저장하고 null을 반환한다.
*/
@org.junit.jupiter.api.Test
void putIfAbsent() {
Map<String, Integer> map = new HashMap<>();
map.put("John", 5);
assertEquals(map.putIfAbsent("John", 10), 5); // 존재하는 경우, value값을 반환한다.
assertEquals(map.size(), 1);
assertNull(map.putIfAbsent("John2", 10)); // 없는 경우, null로 반환하고 map에 저장함.
assertEquals(map.size(), 2);
// {John2=10, John=5}
// System.out.println(map.toString());
}
/*
* default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction);
*
* - key: Map의 key 값
* - mappingFunction: mappingFunction 람다 함수는 key 값이 존재하지 않을 때만 실행된다.
* - 반환값:
* - key값이 존재하는 경우 Map의 value값을 반환한다.
* - key값이 존재하지 않는 경우 Map에 새로운 key와 value(mappingFunction 람다 함수를 실행한 결과) 값을 저장한다.
*/
@org.junit.jupiter.api.Test
void computeIfAbsent() {
Map<String, Integer> map = new HashMap<>();
map.put("John", 5);
assertEquals(map.computeIfAbsent("John", key -> key.length()), 5); // 존재하면 value값을 반환함.
assertEquals(map.size(), 1);
// 없으면 2번째 인자 함수를 실행한 결과를 반환하고 map에도 추가가 된다.
assertEquals(map.computeIfAbsent("John2", key -> key.length()), "John2".length());
assertNotNull(map.get("John2"));
assertEquals(map.size(), 2);
assertNull(map.computeIfAbsent("John3", key -> null));
assertEquals(map.size(), 2);
// {John2=5, John=5}
// System.out.println(map.toString());
}
/*
* default V compute(K key,
* BiFunction<? super K, ? super V, ? extends V> remappingFunction);
*
* compute는 key와 remappingFunction을 인자로 받고 key가 존재해야
* value 값을 인자로 넘겨준 remappingFunction 람다 함수의 결과로 업데이트가 된다.
* key 값이 존재하지 않는 경우에는 NullPointerException이 발생.
*
*/
@org.junit.jupiter.api.Test
void compute() {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 10);
map.put("orange", 20);
map.put("mango", 30);
Integer resultValue = map.compute("mango", (k, v) -> v + 50);
// System.out.println(resultValue); // 80
assertEquals(map.get("mango"), 30 + 50);
//map.compute("banana", (k, v) -> v + 50); // key값이 존재하지 않으므로 NPE발생.
assertNull(map.get("banana"));
}
/*
* default V compute(K key,
* BiFunction<? super K, ? super V, ? extends V> remappingFunction);
*
* - 반환값:
* - key값이 존재하는 경우 remappingFunction 람다 함수 실행결과로 value값이 업데이트된다.
* - key값이 존재하지 않는 경우 null을 반환한다.
*
*/
@org.junit.jupiter.api.Test
void computeIfPresent() {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 10);
map.put("orange", 20);
map.put("mango", 30);
map.computeIfPresent("test", (k, v) -> v + 10); // key가 존재하지 않으므로 null을 반환.
assertNull(map.get("test"));
map.computeIfPresent("mango", (k, v) -> v + 10);
assertEquals(map.get("mango"), 30 + 10);
}
/*
* default V merge(K key, V value,
* BiFunction<? super K, ? super V, ? extends V> remappingFunction);
*
* - 반환값:
* - key값이 존재하는 경우
* - Case1: remappingFunction 함수 결과가 null이 아니면, 람다 함수 실행결과로 value가 업데이트 된다.
* - Case2: remappingFunction 함수 결과가 null이면, map에서 해당 key를 삭제한다.
* - key값이 존재하지 않는 경우 Map에 key, value 값이 추가된다.
*
*/
@org.junit.jupiter.api.Test
void merge() {
Map<String, Integer> map = new HashMap<>();
map.put("apple", 10);
map.put("orange", 20);
map.put("mango", 30);
// key값이 존재를 하면, 해당 key의 값을 remapping 함수의 결과 값으로 바꾼다.
map.merge("mango", 40, (k, v) -> map.get("apple") + 100);
assertEquals(map.get("mango"), 110);
// key가 존재하고 remapping 함수의 결과가 null이면 map에서 해당 key를 삭제한다.
map.merge("mango", 30, (k, v) -> map.get("banana"));
assertNull(map.get("mango"));
assertEquals(map.size(), 2);
// key가 존재하지 않으면, key, value값을 추가함.(두번째 인자 값을 사용)
map.merge("banana", 40, (k, v) -> map.get("apple") + 120);
assertEquals(map.get("banana"), 40);
assertEquals(map.size(), 3);
System.out.println(map.toString());
}
/*
* default V getOrDefault(Object key, V defaultValue)
*
* - 반환값:
* - key값이 존재하는 경우 Map의 value값을 반환한다.
* - key값이 존재하지 않는 경우 defaultValue를 반환한다.
*
*/
@org.junit.jupiter.api.Test
void getOrDefault() {
String str = "test";
Map<Character, Integer> map1 = new HashMap<>();
Map<Character, Integer> map2 = new HashMap<>();
// getOrDefault를 사용하지 않는 경우
for (char c : str.toCharArray()) {
if (map2.containsKey(c))
map2.put(c, map2.get(c) + 1);
else
map2.put(c, 1);
}
// getOrDefault를 사용하는 경우
for (char c : str.toCharArray()) {
map1.put(c, map1.getOrDefault(c, 0) + 1);
}
assertEquals(map1, map2);
// {s=1, t=2, e=1}
// System.out.println(map1.toString());
// System.out.println(map2.toString());
}
}