MultiSet
和Set不同的是MultiSet可以把重复的元素放入集合,你可能会说这和 Set 接口的契约冲突,因为 Set 接口的JavaDoc里面规定不能放入重复元素。事实上,Multiset 并没有实现 java.util.Set 接口,它更像是一个 Bag。普通的 Set 就像这样 :[car, ship, bike],而 Multiset 会是这样 : [car x 2, ship x 6, bike x 3]。Multiset有一个有用的功能,就是跟踪每种对象的数量,所以你可以用来进行数字统计。
常用实现 Multiset 接口的类有:
- HashMultiset: 元素存放于 HashMap
- LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列顺序由第一次放入的顺序决定
- TreeMultiset:元素被排序存放于TreeMap
- EnumMultiset: 元素必须是 enum 类型
- ImmutableMultiset: 不可修改的 Mutiset
Guava Collections 都是以 create 或是 of 这样的静态方法来构造对象。这是因为这些集合类大多有多个参数的私有构造方法,由于参数数目很多,客户代码程序员使用起来就很不方便。而且以这种方式可以返回原类型的子类型对象。另外,对于创建范型对象来讲,这种方式更加简洁。
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) : 去除出现给给定集合参数的所有的元素
import java.util.Set;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
/**
* 统计单词出现的次数
* multiset 无序可以重复 使用count方法可以统计单词出现的次数
* @author Administrator
*
*/
public class Demo03 {
public static void main(String[] args) {
String str = "this is a cat and that is a mice where is the food ";
String[] arr = str.split(" ");
//存储到MutiSet中
Multiset<String> set = HashMultiset.create();
for(String temp:arr){
set.add(temp);
}
System.out.println(set.size());
set.remove("is",1);
Set<String> letters = set.elementSet();
for(String temp:letters){
//因为前面单词is已经移除一次了,所以打印出的会是2
System.err.println(temp+"--"+set.count(temp));
}
// for(Multiset.Entry<String> temp:set.entrySet()){
// System.out.println(temp.getElement()+"--"+temp.getCount());
// }
}
}
MultiMap
有时候我们需要这样的数据类型Map(String,Collection(String)),也就是所谓的一键多值,guava中的Multimap就是为了解决这类问题的。Multimap提供了丰富的实现,所以你可以用它来替代程序里的Map(K, Collection(V)),具体的实现如下:
import java.util.Collection;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
/**
* 测试Multimap 其是map的延伸,不过其中的键可以重复,意思就是可以一键多值
* @author Administrator
*
*/
public class Demo04 {
public static void main(String[] args) {
Multimap<String,String> multimap = ArrayListMultimap.create();
// 添加键值对
multimap.put("Fruits", "Bannana");
// 给Fruits元素添加另一个元素
multimap.put("Fruits", "Apple");
multimap.put("Fruits", "Pear");
multimap.put("Vegetables", "Carrot");
System.out.println(multimap.size()); //size为4说明就算键相同,值也不会被覆盖
Collection<String> col = multimap.get("Fruits");
System.out.println(col);
// 移除一个值
multimap.remove("Fruits","Pear");
System.out.println(multimap.get("Fruits")); // [Bannana, Pear]
// 移除所有的值
multimap.removeAll("Fruits");
System.out.println(multimap.get("Fruits")); // [] (Empty Collection
}
}
输出结果:4
[Bannana, Apple, Pear]
[Bannana, Apple]
[]
BiMap
我们知道Map是一种键值对映射,这个映射是键到值的映射,而BiMap首先也是一种Map,他的特别之处在于,既提供键到值的映射,也提供值到键的映射,所以它是双向Map。BiMap的值键对的Map可以通过inverse()方法得到。
BiMap的常用实现有:
HashBiMap: key 集合与 value 集合都有 HashMap 实现
EnumBiMap: key 与 value 都必须是 enum 类型
ImmutableBiMap: 不可修改的 BiMap
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
/**
* 测试Bimap,双向map,也就是键和值都不能重复,而且可以通过值来找键
* @author Administrator
*
*/
public class Demo05 {
public static void main(String[] args) {
BiMap<String,String> map = HashBiMap.create();
map.put("星期一","Monday");
map.put("星期二","Tuesday");
map.put("星期三","Wednesday");
map.put("星期四","Thursday");
map.put("星期五","Friday");
map.put("星期六","Saturday");
map.put("星期日","Sunday");
System.out.println("星期日的英文名是" + map.get("星期日"));
System.out.println("Sunday的中文是" + map.inverse().get("Sunday"));
System.out.println(map.inverse().inverse()==map);
}
}