Guava - 强大的集合工具Multisets

一、简介

Guava在原有的Java集合类型上新增了多种集合类型,而其中一个类型就是MultiSet.
MultiSet的使用场景十分常见,基本上用于统计次数相关的业务都可以用到它.
MultiSets工具类基本上就是为它而诞生的.提供了如验证包含关系、批量移除元素出现次数等实用方法......

二、常用方法

1、验证super Multiset是否包含sub MultiSet方法 - containsOccurrences()

containsOccurrences(Multiset superMultiset, Multiset subMultiset)方法将会比较superMultiset是否完全包含subMultiset,如果完全包含返回TRUE,否则返回FALSE.

简单实验代码:

        Multiset multisetSup = TreeMultiset.create();
        multisetSup.add(1, 5);
        multisetSup.add(2, 10);

        //元素节点不完全包含
        Multiset multisetSub1 = TreeMultiset.create();
        multisetSub1.add(1, 5);
        multisetSub1.add(3, 10);

        //元素节点完全包含但是出现次数不完全包含
        Multiset multisetSub2 = TreeMultiset.create();
        multisetSub2.add(1, 6);
        multisetSub2.add(2, 9);

        //元素节点以及出现次数都完全包含
        Multiset multisetSub3 = TreeMultiset.create();
        multisetSub3.add(1, 4);
        multisetSub3.add(2, 9);

        //测试containsOccurrences方法
        //和Collection.containsAll不同,它只校验元素是否被包含,并且会忽略掉count的存在
        System.out.println("=======================测试containsOccurrences()方法 - 元素节点不完全包含=======================" + Multisets.containsOccurrences(multisetSup, multisetSub1));
        System.out.println("=======================测试containsOccurrences()方法 - 元素节点完全包含但是出现次数不完全包含=======================" + Multisets.containsOccurrences(multisetSup, multisetSub2));
        System.out.println("=======================测试containsOccurrences()方法 - 元素节点以及出现次数都完全包含=======================" + Multisets.containsOccurrences(multisetSup, multisetSub3));

实验结果:

=======================测试containsOccurrences()方法 - 元素节点不完全包含=======================false
=======================测试containsOccurrences()方法 - 元素节点完全包含但是出现次数不完全包含=======================false
=======================测试containsOccurrences()方法 - 元素节点以及出现次数都完全包含=======================true

可以发现实验结果与预期一致.

值得注意的是:
superMultisetsubMultiset都不能为NULL.

2、移除指定MultiSet元素出现次数方法 - removeOccurrences()

MultiSets提供了移除指定MultiSet元素次数的方法 - removeOccurrences( Multiset multisetToModify, Multiset occurrencesToRemove).
它的作用为将需要移除的occurrencesToRemove作用于待修改的multisetToModify上,multisetToModify将移除掉和occurrencesToRemove节点相同的出现次数.如果原有multisetToModify发生了变化则返回TRUE,否则返回FALSE.

简单实验代码:

        //测试removeOccurrences方法
        //它将会把需要修改的Multiset以及将要移除的MultiSet做扣减
        //当前方法的含义理解为批量删除multisetToModify中的指定节点存在数量
        //MultiSet提供了remove()方法可以删除存在的节点以及删除指定节点的次数,为啥不直接支持批量的而要放在MultiSets中呢?
        //MultiSet提供了removeAll()方法支持批量删除节点,为什么此时不能支持删除指定的次数?
        //这是有什么考虑在里面么?我认为从使用者角度来说MultiSet直接支持了就不用在多调用一个工具类岂不是更方便?

        //初始化待修改的MultiSet
        Multiset multisetToModify = TreeMultiset.create();
        multisetToModify.add(1, 5);
        multisetToModify.add(2, 5);

        //初始化作为指定条件的MultiSet
        Multiset removeTo = TreeMultiset.create();
        //扣减存在的元素且出现次数小于原有元素出现次数
        removeTo.add(1, 3);
        //扣减存在的元素且出现次数大于原有元素出现次数
        removeTo.add(2, 6);
        //扣减不存在的元素
        removeTo.add(3, 1);
        System.out.println("=======================测试removeOccurrences()方法=======================" + Multisets.removeOccurrences(multisetToModify, removeTo));
        System.out.println(multisetToModify);

实验结果:

=======================测试removeOccurrences()方法=======================true
[1 x 2]

可以发现实验结果与预期一致.对于存在的节点扣除需要移除的出现次数,对于不存在的节点则不进行任何操作.

值得注意的是:
multisetToModifyoccurrencesToRemove都不能为NULL.

3、保留覆盖方法 - retainOccurrences()

当我们只想对原有Multiset保留指定的信息时,Multisets提供了retainOccurrences( Multiset multisetToModify, Multiset multisetToRetain)方法,它就完美实现了保留逻辑,将想要保留的数据信息multisetToRetain作用于待调整的数据multisetToModify上面,如果multisetToModify发生了变化返回TRUE,否则返回FALSE.

实验代码:

        //测试retainOccurrences()方法
        //它会将需要修改的MultiSet与需要保留的MultiSet进行比对,返回是否被修改
        //如果被修改 - 那么原有的节点以及节点对应的数值将会被替换
        //类似于replace()方法
        Multiset removeFrom = TreeMultiset.create();
        removeFrom.add(1, 5);
        removeFrom.add(2, 5);
        removeFrom.add(4, 5);

        Multiset toRetain = TreeMultiset.create();
        //保留已存在的节点
        toRetain.add(1, 4);
        //保留已存在的节点
        toRetain.add(2, 5);
        //保留不存在的节点
        toRetain.add(3, 6);

        System.out.println("=======================测试retainOccurrences()方法=======================" + Multisets.retainOccurrences(removeFrom, toRetain));
        System.out.println(removeFrom);

实验结果:

=======================测试retainOccurrences()方法=======================true
[1 x 4, 2 x 5]

可以发现相交的节点都保留multisetToRetain中的节点信息,其余的都被干掉了.

值得注意的是:
multisetToModifyoccurrencesToRetain都不能为NULL.

4、两个MultiSet取交集方法 - intersection()

当然比较常用的取交集的方法MultiSets也是提供的 - intersection( final Multiset multiset1, final Multiset multiset2),它会对两个Multiset的元素取交集,交集的出现次数已最小的次数为准.

实验代码:

        //测试交集方法 - 交集的结果以最小集为准
        Multiset section1 = TreeMultiset.create();
        section1.add(1, 5);
        section1.add(2, 5);

        Multiset section2 = TreeMultiset.create();
        section2.add(1, 4);
        section2.add(2, 5);
        section2.add(3, 6);

        Multiset intersection = Multisets.intersection(section1, section2);

        System.out.println("=======================测试intersection()方法=======================" + intersection);

实验结果:

=======================测试intersection()方法=======================[1 x 4, 2 x 5]

可以发现目标结果与预期一致.

值得注意的是:
multiset1multiset2都不能为NULL.

5、根据元素出现次数降序排序方法 - copyHighestCountFirst

Multisets提供了降序排序方法 - copyHighestCountFirst(Multiset multiset),它会返回一个不可变的视图,视图元素顺序按照元素出现次数到下排序.

实验代码:

        //测试通过元素出现次数降序排序方法
        Multiset multiset = TreeMultiset.create();
        //测试元素出现次数相同 - 录入不规则顺序 - before
        multiset.add(12, 7);
        multiset.add(1, 5);
        multiset.add(2, 6);
        //测试元素出现次数相同 - 录入不规则顺序 - before
        multiset.add(11, 7);
        multiset.add(3, 7);
        //测试元素出现次数相同 - 录入不规则顺序 - after
        multiset.add(10, 7);
        multiset.add(4, 8);
        multiset.add(5, 9);

        System.out.println("=========================测试copyHighestCountFirst方法()=====================" + Multisets.copyHighestCountFirst(multiset));

实验结果:

=========================测试copyHighestCountFirst方法()=====================[5 x 9, 4 x 8, 3 x 7, 10 x 7, 11 x 7, 12 x 7, 2 x 6, 1 x 5]

可以发现当出现元素出现次数不同的时候,按照元素出现次数最多的元素降序排序,相同的时候......最终返回的是一个不可变的视图

......未完待续

你可能感兴趣的:(Guava - 强大的集合工具Multisets)