项目中使用到了这个类,在这里简单记录一下
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);
}