Google Guava 的 Multimap 的使用

項目中使用到了這個類,在這裏簡單記錄一下

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);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章