Guava引进了JDK里没有的,但是非常有用的一些新的集合类型。所有这些新集合类型都能和JDK里的集合平滑集成。Guava集合非常精准地实现了JDK定义的接口。Guava中定义的新集合有:
  Multiset
  SortedMultiset
  Multimap
  ListMultimap
  SetMultimap
  BiMap
  ClassToInstanceMap
  Table

  Multiset集合

  Multiset是什么?顾名思义,Multiset和Set的区别就是可以保存多个相同的对象。在JDK中,List和Set有一个基本的区别,就是List可以包含多个相同对象,且是有顺序的,而Set不能有重复,且不保证顺序(有些实现有顺序,例如LinkedHashSet和SortedSet等)所以Multiset占据了List和Set之间的一个灰色地带:允许重复,但是不保证顺序。 
  常见使用场景:Multiset有一个有用的功能,就是跟踪每种对象的数量,所以你可以用来进行数字统计。 常见的普通实现方式如下:

  1. @Test
  2. public void testWordCount(){
  3. String strWorld="wer|dffd|ddsa|dfd|dreg|de|dr|ce|ghrt|cf|gt|ser|tg|ghrt|cf|gt|" +
  4. "ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr|wer|dffd|ddsa|dfd|dreg|de|dr|" +
  5. "ce|ghrt|cf|gt|ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr";
  6. String[] words=strWorld.split("\\|");
  7. Map<String, Integer> countMap = new HashMap<String, Integer>();
  8. for (String word : words) {
  9. Integer count = countMap.get(word);
  10. if (count == null) {
  11. countMap.put(word, 1);
  12. }
  13. else {
  14. countMap.put(word, count + 1);
  15. }
  16. }
  17. System.out.println("countMap:");
  18. for(String key:countMap.keySet()){
  19. System.out.println(key+" count:"+countMap.get(key));
  20. }
  21. }

  上面的代码实现的功能非常简单,用于记录字符串在数组中出现的次数。这种场景在实际的开发过程还是容易经常出现的,如果使用实现Multiset接口的具体类就可以很容易实现以上的功能需求:

  1. public void testMultsetWordCount(){
  2. String strWorld="wer|dfd|dd|dfd|dda|de|dr";
  3. String[] words=strWorld.split("\\|");
  4. List<String> wordList=new ArrayList<String>();
  5. for (String word : words) {
  6. wordList.add(word);
  7. }
  8. Multiset<String> wordsMultiset = HashMultiset.create();
  9. wordsMultiset.addAll(wordList);
  10.  
  11. for(String key:wordsMultiset.elementSet()){
  12. System.out.println(key+" count:"+wordsMultiset.count(key));
  13. }
  14. }

  Multiset主要方法

  Multiset接口定义的接口主要有:
    add(E element) :向其中添加单个元素
    add(E element,int occurrences) : 向其中添加指定个数的元素
    count(Object element) : 返回给定参数元素的个数
    remove(E element) : 移除一个元素,其count值 会响应减少
    remove(E element,int occurrences): 移除相应个数的元素
    elementSet() : 将不同的元素放入一个Set中
    entrySet(): 类似与Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
    setCount(E element ,int count): 设定某一个元素的重复次数
    setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
    retainAll(Collection c) : 保留出现在给定集合参数的所有的元素 
    removeAll(Collectionc) : 去除出现给给定集合参数的所有的元素

  常用方法实例:

  1. @Test
  2. public void testMultsetWordCount(){
  3. String strWorld="wer|dfd|dd|dfd|dda|de|dr";
  4. String[] words=strWorld.split("\\|");
  5. List<String> wordList=new ArrayList<String>();
  6. for (String word : words) {
  7. wordList.add(word);
  8. }
  9. Multiset<String> wordsMultiset = HashMultiset.create();
  10. wordsMultiset.addAll(wordList);
  11.  
  12. //System.out.println("wordsMultiset:"+wordsMultiset);
  13.  
  14. for(String key:wordsMultiset.elementSet()){
  15. System.out.println(key+" count:"+wordsMultiset.count(key));
  16. }
  17.  
  18. if(!wordsMultiset.contains("peida")){
  19. wordsMultiset.add("peida", 2);
  20. }
  21. System.out.println("============================================");
  22. for(String key:wordsMultiset.elementSet()){
  23. System.out.println(key+" count:"+wordsMultiset.count(key));
  24. }
  25.  
  26. if(wordsMultiset.contains("peida")){
  27. wordsMultiset.setCount("peida", 23);
  28. }
  29.  
  30. System.out.println("============================================");
  31. for(String key:wordsMultiset.elementSet()){
  32. System.out.println(key+" count:"+wordsMultiset.count(key));
  33. }
  34.  
  35. if(wordsMultiset.contains("peida")){
  36. wordsMultiset.setCount("peida", 23,45);
  37. }
  38.  
  39. System.out.println("============================================");
  40. for(String key:wordsMultiset.elementSet()){
  41. System.out.println(key+" count:"+wordsMultiset.count(key));
  42. }
  43.  
  44. if(wordsMultiset.contains("peida")){
  45. wordsMultiset.setCount("peida", 44,67);
  46. }
  47.  
  48. System.out.println("============================================");
  49. for(String key:wordsMultiset.elementSet()){
  50. System.out.println(key+" count:"+wordsMultiset.count(key));
  51. }
  52. }

    说明:setCount(E element,int oldCount,int newCount): 方法,如果传入的oldCount和element的不一致的时候,是不能讲element的count设置成newCount的。需要注意。

  Multiset不是Map

  需要注意的是Multiset不是一个Map<E,Integer>,尽管Multiset提供一部分类似的功能实现。其它值得关注的差别有:
  Multiset中的元素的重复个数只会是正数,且最大不会超过Integer.MAX_VALUE。设定计数为0的元素将不会出现multiset中,也不会出现elementSet()和entrySet()的返回结果中。
  multiset.size() 方法返回的是所有的元素的总和,相当于是将所有重复的个数相加。如果需要知道每个元素的个数可以使用elementSet().size()得到.(因而调用add(E)方法会是multiset.size()增加1).
  multiset.iterator() 会循环迭代每一个出现的元素,迭代的次数与multiset.size()相同。 iterates over each occurrence of each element, so the length of the iteration is equal to multiset.size().
  Multiset 支持添加、移除多个元素以及重新设定元素的个数。执行setCount(element,0)相当于移除multiset中所有的相同元素。
  调用multiset.count(elem)方法时,如果该元素不在该集中,那么返回的结果只会是0。

  Multiset的实现 

  Guava提供了Multiset的多种实现,这些实现基本对应了JDK中Map的实现: 
  Map                        Corresponding Multiset   Supports null elements
  HashMap                  HashMultiset                      Yes
  TreeMap                   TreeMultiset                       Yes (if the comparator does)
  LinkedHashMap         LinkedHashMultiset             Yes
  ConcurrentHashMap  ConcurrentHashMultiset       No
  ImmutableMap          ImmutableMultiset               No

MultiSet的更多相关文章

  1. C++ std::multiset

    std::multiset template < class T, // multiset::key_type/value_type class Compare = less<T>, ...

  2. Guava学习笔记:Guava新增集合类型-Multiset

    Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口.Guava中定义的新集合有: Multi ...

  3. [Google Guava]学习--新集合类型Multiset

    Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接口. Multiset主要方法介绍: a ...

  4. UVA11136Hoax or what( multiset的应用)

    题目链接 题意:n天,每天往一个箱子里放m个数,放完之后取最大的Max和最小的min做差,并把这两个数去掉,求n天之后的和 multiset 和 set的原理是相似的,multiset可以存多个相同的 ...

  5. 4.2 set和multiset

    使用必须包含头文件set 1)multiset *:定义 如果不给第二个参数,默认less<key>,即用<来进行. 例如: A是一个类的名字,则可以定义一个容器对象如下: mult ...

  6. STL(multiset) UVA 11020 Efficient Solutions

    题目传送门 题意:训练指南P228 分析:照着书上的做法,把点插入后把它后面不占优势的点删除,S.size ()就是优势的人数,时间复杂度O (nlogn) #include <bits/std ...

  7. Codeforces Round #367 (Div. 2) D. Vasiliy's Multiset(可持久化Trie)

    D. Vasiliy's Multiset time limit per test 4 seconds memory limit per test 256 megabytes input standa ...

  8. STL中的set/multiset小结

    (1)使用set/multiset之前必须包含头文件<set>:#include<set> (2)namespace std{ template <class T, cl ...

  9. STL--集和多集(set/multiset)

    与基本容器相比,关联容器更注重快速和高效地检索数据的能力.这些容器是根据键值(key)来检索数据的,键可以是值也可以是容器中的某一成员.这一类中的成员在初始化后都是按一定顺序排好序的. 本文地址:ht ...

  10. C++ Set & MultiSet

    转自http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177627.html STL Set介绍集合(Set)是一种包含已排序对象的关联容器 ...

随机推荐

  1. SPOJ LCS 后缀自动机

    用后缀自动机求两个长串的最长公共子串,效果拔群.多样例的时候memset要去掉. 解题思路就是跟CLJ的一模一样啦. #pragma warning(disable:4996) #include< ...

  2. vlc/ffmepg/mplayer/gstreamer/openmax/mpc/ffdshow/directshow

    一些应该学习的开源框架与库用途和差别 一.播放器层次 这个层次上,是直接可以用的软件,已经做完了一切工作,如果我们需要用他们,是不需要写一行代码的,编译通过就可以拿来使用了,对于国内这些山寨公司来说, ...

  3. 入门视频采集与处理(BT656简介)

    入门视频采集与处理(BT656简介) http://ticktick.blog.51cto.com/823160/553535 1.  帧的概念(Frame) 一个视频序列是由N个帧组成的,采集图像的 ...

  4. 前端自动化神器gulp使用记录

    1.安装压缩图片插件的时候,由于网络原因,死活安装不成功.由于imagemin本身就包含很多插件,安装的时候卡住了,很是郁闷.如果要压缩png图片,那就单独安装imagemin-pngquant压缩插 ...

  5. C# progressbar 用法

    http://blog.chinaunix.net/uid-9236609-id-3069624.html progressBar1.Maximum = 100;//设置最大长度值          ...

  6. ios高版本SDK在低版本真机调试

    将build settings的ios deployment target改为对应真机系统版本即可

  7. js学习对象创建

    Object.extend = function(destination, source) {for (var property in source) {    destination[propert ...

  8. [HIHO1184]连通性二·边的双连通分量(双连通分量)

    题目链接:http://hihocoder.com/problemset/problem/1184 题意裸,写个博客记下输出姿势. /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mi ...

  9. sublime中文乱码

    今天在用sublime的时候,又出现乱码的情况了.弹层如下: 检测了一下,当前文件,sublime编辑器左下角显示如下: 显示的是 ASCII 编码的文件,而其他没有没问题的页面显示的的 GBK(或G ...

  10. CSS在不同浏览器兼容问题,margin偏移/offset溢出等

    margin在垂直取值时取最大值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...