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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值