Guava Multimap
1. 메이븐 종속성
종속성을 추가한다.
1
2
3
4
5
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
최신 버전은 여기에서 찾을 수 있다.
2. 멀티맵 구현
Guava Multimap의 경우 동일한 키에 대해 두 개의 값을 추가하면 두 번째 값이 첫 번째 값을 무시하지 않는다. 대신 결과 맵에 두 개의 값이 있다.
1
2
3
4
5
6
7
String key = "a-key";
Multimap<String, String> map = ArrayListMultimap.create();
map.put(key, "firstValue");
map.put(key, "secondValue");
assertEquals(2, map.size());
Map의 내용을 출력하면 다음이 출력된다.
1
{a-key=[firstValue, secondValue]}
“a-key” 키로 값을 가져올 때 “firstValue” 및 “secondValue”를 결과로 포함하는 Collection
1
Collection<String> values = map.get(key);
출력 값은 다음과 같이 출력된다.
1
[firstValue, secondValue]
3. 표준 Map과 비교
java.util
패키지의 표준 맵은 동일한 키에 여러 값을 할당하는 기능을 제공하지 않는다. 동일한 키를 사용하여 맵에 두 개의 값을 put()
하는 간단한 경우이다.
1
2
3
4
5
6
7
String key = "a-key";
Map<String, String> map = new LinkedHashMap<>();
map.put(key, "firstValue");
map.put(key, "secondValue");
assertEquals(1, map.size());
결과 맵에는 첫 번째 값을 재정의하는 두 번째 put()
작업 때문에 하나의 요소(“secondValue”)만 있다. Guava의 Multimap과 동일한 동작을 수행하려면 값 유형으로 List<String>
이 있는 맵을 만들어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
String key = "a-key";
Map<String, List<String>> map = new LinkedHashMap<>();
List<String> values = map.get(key);
if(values == null) {
values = new LinkedList<>();
values.add("firstValue");
values.add("secondValue");
}
map.put(key, values);
assertEquals(1, map.size());
분명히 사용하기가 그리 편리하지 않다. 그리고 코드에 이러한 요구 사항이 있는 경우 Guava의 Multimap이 java.util.Map
보다 더 나은 선택이 될 수 있다.
여기서 한 가지 주의할 점은 두 개의 요소가 포함된 목록이 있지만 size()
메서드는 1을 반환한다. 멀티맵에서 size()
는 맵에 저장된 실제 값 수를 반환하지만 keySet().size()
는 고유 키 수를 반환한다.
4. 멀티맵의 장점
멀티맵은 일반적으로 Map<K, Collection<V>>
가 나타날 수 있는 위치에서 사용된다. 차이점은 다음과 같다.
put()
으로 항목을 추가하기 전에 빈 컬렉션을 채울 필요가 없다.get()
메서드는 null을 반환하지 않고 빈 컬렉션만 반환한다(Map<String, Collection<V>>
와 같이 null에 대해 확인할 필요가 없음).키는 하나 이상의 값에 매핑되는 경우에만 Multimap에 포함된다. 키에 연결된 값이 0이 되도록 하는 모든 작업은 Multimap에서 해당 키를 제거하는 효과가 있다(
Map<String, Collection<V>>
에서 컬렉션에서 모든 값을 제거하더라도 여전히 빈 컬렉션을 유지한다. 불필요한 메모리 오버헤드).총 항목 값 개수는
size()
로 사용할 수 있다.