項目中使用到了這個類,在這裏簡單記錄一下
com.google.common.collect 這個包裏封裝了很多集合類,比如 Multimap,那麼這個類和 Map 有什麼區別呢?
Guava 文檔 Multimap (Guava: Google Core Libraries for Java 22.0 API)
A collection that maps keys to values, similar to Map, but in which each key may be associated with multiple values. You can visualize the contents of a multimap either as a map from keys to nonempty collections of values:
- a → 1, 2
- b → 3
… or as a single “flattened” collection of key-value pairs:
- a → 1
- a → 2
- b → 3
可以看到,Multimap 類似於 Map,但是它不是 Map,它是 “A collection that maps keys to values”,即,將 keys 映射到 values 的集合,而 Map 是 “An object that maps keys to values” 。在 Multimap 中,一個 key 可以對應多個 values。
並且在 Multimap 中,不會有任何鍵映射到空集合,也就是說,一個鍵要麼至少到一個值,要麼根本就不在Multimap中。
所以我們可以將 Multimap 看作一個 從 keys 映射到非空 values 集合的 Map
就像文檔中舉的 a、b 的例子,在 Multimap 中你可以看作
- a -> 1,2
- b -> 3
而在 Map 中只能是 - a -> 1
- a -> 2
- b -> 3
不過,在 Multimap 中 a、b 實際上還是以第二種方式存儲的,所以此時 multimap 的 size 是 3 而不是 2.
那麼,我們什麼時候需要使用 Multimap 呢?
當我們需要讓一個 key 對應多個 value 時,可以使用 Multimap,因爲 Java 原生的 Map 一個 key 是不能存入重複 value 值的,在 put 時會覆蓋。而 Multimap 就相當於一個 key-value 的 集合,還是拿上面的 a、b 舉例,它在 Multimap 中的存儲形式就相當於集合 {a -> 1, a -> 2, b -> 3}
具體到項目中就是,因爲我想構建一個部門的層級樹,所以在存儲時,需要一個數據結構能夠存儲 level 以及對應的 DeptLevelDto 適配對象,如果我用原生 Java 來實現,我需要這麼做
Map<String, List<DeptLevelDto>> dtoMap = new HashMap<String,List<DeptLevelDto>>();
然後再 put 的時候,我需要先 check null
public void putDeptLevelDto(String level, List<DeptLevelDto> deptDto) {
List<DeptLevelDto> dtoList = dtoMap.get(level);
if (dtoList == null) {
dtoList = new ArrayList<>();
dtoMap.put(level, dtoList);
}
dtoList.add(deptDto);
}
只是 put 操作就需要很多代碼了,而如果我們使用 Multimap 的話,僅需要這幾行就可以了
Multimap<String, DeptLevelDto> levelDtoMultimap = ArrayListMultimap.create();
for (DeptLevelDto dto : dtoList) {
levelDtoMultimap.put(dto.getLevel(), dto);
}