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有一个有用的功能,就是跟踪每种对象的数量,所以你可以用来进行数字统计。 常见的普通实现方式如下:

 @Test
public void testWordCount(){
String strWorld="wer|dffd|ddsa|dfd|dreg|de|dr|ce|ghrt|cf|gt|ser|tg|ghrt|cf|gt|" +
"ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr|wer|dffd|ddsa|dfd|dreg|de|dr|" +
"ce|ghrt|cf|gt|ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr";
String[] words=strWorld.split("\\|");
Map<String, Integer> countMap = new HashMap<String, Integer>();
for (String word : words) {
Integer count = countMap.get(word);
if (count == null) {
countMap.put(word, 1);
}
else {
countMap.put(word, count + 1);
}
}
System.out.println("countMap:");
for(String key:countMap.keySet()){
System.out.println(key+" count:"+countMap.get(key));
}
}

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

 public void testMultsetWordCount(){
String strWorld="wer|dfd|dd|dfd|dda|de|dr";
String[] words=strWorld.split("\\|");
List<String> wordList=new ArrayList<String>();
for (String word : words) {
wordList.add(word);
}
Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(wordList); for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
}
}

  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) : 去除出现给给定集合参数的所有的元素

  常用方法实例:

@Test
public void testMultsetWordCount(){
String strWorld="wer|dfd|dd|dfd|dda|de|dr";
String[] words=strWorld.split("\\|");
List<String> wordList=new ArrayList<String>();
for (String word : words) {
wordList.add(word);
}
Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(wordList); //System.out.println("wordsMultiset:"+wordsMultiset); for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
} if(!wordsMultiset.contains("peida")){
wordsMultiset.add("peida", 2);
}
System.out.println("============================================");
for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
} if(wordsMultiset.contains("peida")){
wordsMultiset.setCount("peida", 23);
} System.out.println("============================================");
for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
} if(wordsMultiset.contains("peida")){
wordsMultiset.setCount("peida", 23,45);
} System.out.println("============================================");
for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
} if(wordsMultiset.contains("peida")){
wordsMultiset.setCount("peida", 44,67);
} System.out.println("============================================");
for(String key:wordsMultiset.elementSet()){
System.out.println(key+" count:"+wordsMultiset.count(key));
}
}

    说明: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. Searching a 2D Sorted Matrix Part I

    Write an efficient algorithm that searches for a value in an n x m table (two-dimensional array). Th ...

  2. POJ3461 Oulipo KMP算法

    这个算法去年的这个时候就已经听过了,看毛片算法哈哈..不过理解它确实花了我很久的时间..以致于我一直很排斥字符串的学习,因为总觉得太难了,但是有些硬骨头还是要啃的,这个寒假就啃啃字符串还有一些别的东西 ...

  3. POJ 1062 昂贵的聘礼(Dijkstra)

    题意 : 真真是做POJ第一次遇到中文题,好吧,虽然语言通了,我一开始也没看懂样例什么意思,题意的话就是说这个探险家想娶酋长的女儿,但是没有钱,酋长说他可以用祭司的水晶球或者皮袄来换取少花一部分钱,同 ...

  4. POJ3083Children of the Candy Corn

    题意:给你一个迷宫,入口处标为S,出口处标为E,可以走的地方为“.”,不可以走的地方为#,求左转优先时从出口到入口的路程,再求右转优先时,出口到入口的路程,最后求从出口到入口的最短路程. 思路:求前两 ...

  5. hdu 3972 1 M possible

    一般做法: 显然的超内存 #include<stdio.h> #include<algorithm> using namespace std; ],ans[]; int mai ...

  6. scanf()函数用法小结

    scanf()函数是格式化输入函数,它从标准输入设备(键盘) 读取输入的信息. 其调用格式为:      scanf("<格式化字符串>",<地址表>); ...

  7. DOS命令 Net config server Net config workstation

    DOS命令 Net config 作用:显示当前运行的可配置服务,或显示并修改某项服务的设置. 格式:net conifg service options 参数:(1)键入不带参数的net conif ...

  8. Linux 查找软件安装路径

    root@kali:~# whereis sqlmap sqlmap: /usr/bin/sqlmap /usr/share/sqlmap /usr/share/man/man1/sqlmap..gz ...

  9. jQuery-瀑布流-浮动布局(一

    jQuery-瀑布流-浮动布局(一)(延迟AJAX加载图片)   瀑布流:这种布局适合于小数据块,每个数据块内容相近且没有侧重.通常,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部 ...

  10. [POJ2398]Toy Storage(计算几何,二分,判断点在线段的哪一侧)

    题目链接:http://poj.org/problem?id=2398 思路RT,和POJ2318一样,就是需要排序,输出也不一样.手工画一下就明白了.注意叉乘的时候a×b是判断a在b的顺时针还是逆时 ...