MultiSet
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的更多相关文章
- C++ std::multiset
std::multiset template < class T, // multiset::key_type/value_type class Compare = less<T>, ...
- Guava学习笔记:Guava新增集合类型-Multiset
Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口.Guava中定义的新集合有: Multi ...
- [Google Guava]学习--新集合类型Multiset
Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接口. Multiset主要方法介绍: a ...
- UVA11136Hoax or what( multiset的应用)
题目链接 题意:n天,每天往一个箱子里放m个数,放完之后取最大的Max和最小的min做差,并把这两个数去掉,求n天之后的和 multiset 和 set的原理是相似的,multiset可以存多个相同的 ...
- 4.2 set和multiset
使用必须包含头文件set 1)multiset *:定义 如果不给第二个参数,默认less<key>,即用<来进行. 例如: A是一个类的名字,则可以定义一个容器对象如下: mult ...
- STL(multiset) UVA 11020 Efficient Solutions
题目传送门 题意:训练指南P228 分析:照着书上的做法,把点插入后把它后面不占优势的点删除,S.size ()就是优势的人数,时间复杂度O (nlogn) #include <bits/std ...
- 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 ...
- STL中的set/multiset小结
(1)使用set/multiset之前必须包含头文件<set>:#include<set> (2)namespace std{ template <class T, cl ...
- STL--集和多集(set/multiset)
与基本容器相比,关联容器更注重快速和高效地检索数据的能力.这些容器是根据键值(key)来检索数据的,键可以是值也可以是容器中的某一成员.这一类中的成员在初始化后都是按一定顺序排好序的. 本文地址:ht ...
- C++ Set & MultiSet
转自http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177627.html STL Set介绍集合(Set)是一种包含已排序对象的关联容器 ...
随机推荐
- POJ 2080 Calendar(很水的模拟)
刚开始一直WA,才发现原来代码中两处减去年份.月份的天数的判断条件用的是>=,虽然最后考虑n=0要退回一天的情况,但还是WA.后来改成>的条件判断,省去了考虑n=0的麻烦,AC. 此题无非 ...
- http://www.aboutyun.com/thread-8792-1-1.html
http://www.aboutyun.com/thread-8792-1-1.html
- iOS开发--SWRevealViewController
SWRevealViewController 是一个比较好的实现Sliding功能的第三方类. 今天跟大家分享一下如何使用SWRevealViewController实现左右菜单滑动功能. 首先,在工 ...
- Hibernate逍遥游记-第9章 Hibernate的映射类型
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- 多线程进行n皇后计算
在浏览zhihu的时候, 看到了这个问题:Linux c++服务器端这条线怎么走? http://www.zhihu.com/question/22608820 , 其中排第一的答案说的很不错.针对他 ...
- [iOS]iPhone利用<极光推送>实现远程推送
准备: 1. 一个Xcode工程 2. 开发者账号 3. 真机 (重要,模拟器无法进行远程推送,因为模拟器没有UDID) 第一步:绑定工程的Bundle Identifer 首先当然要登录https: ...
- UVa 1473 - Dome of Circus 三分
把所有的点都映射到XOZ这个平面的第一象限内,则这个三维问题可以转化二维问题: 求一条直线,使所有点在这条直线的下方,直线与X轴和Z轴围成的三角形旋转形成的圆锥体积最小. 这样转化之后可以看出直线的临 ...
- maven 仓库下载缓慢,怎么解决
maven下载jar的时候会去寻国外的地址,因此造成了下载jar很缓慢,影响开发效率,于是就出现maven镜像地址,可以使我们开发人员迅速下载相关的jar. 在maven的config的setting ...
- android源码编译1
一.环境说明: 1.liunx系统:Ubuntu12.04 2.jdk:sun-java6-jdk 3.g++4.5 gcc4.5 二.android源码的目录结构 |-- Makefile |-- ...
- Java泛型中的extends和super关键字
理解List<? extends T> list, T key, Comparator<? super T> c 这些一般用在方法形参类型上,用于接受泛型对象. 1.List& ...