相信大家對Java中的Map類及其之類有大致的了解,Map類是以鍵值對的形式來存儲元素(Key->Value),但是熟悉Map的人都知道,Map中存儲的Key是唯一的。什么意思呢?就是假如我們有兩個key相同,但value不同的元素需要插入到map中去,那么先前的key對應的value將會被后來的值替換掉。如果我們需要用Map來把相同key的值存在一起,代碼看起來像下面一樣:
~~~
/**
*
*/
package com.wyp.Map;
/**
*@User: 過往記憶
*@Date: 2013-7-9
* Email: wyphao.2007@163.com
*
**/
public class Person {
//姓名
private String name;
//年齡
private int age;
//性別
private String sex;
/**
*
*/
public Person() {
// TODO Auto-generated constructor stub
}
/**
* @param name
* @param age
* @param sex
*/
public Person(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
下面進行
//性別統計
public void genderStatistics(List personList){
if(personList == null){
return;
}
Map<String, List> map = new HashMap<String, List>();
for(Person person : personList){
String sex = person.getSex();
List persons = map.get(sex);
if(persons == null){//第一次加入
persons = new ArrayList();
}
persons.add(person);
map.put(sex, persons);
}
for (Entry<String, List> entry : map.entrySet()) {
String key = entry.getKey();
System.out.println(key + "\t" + entry.getValue());
}
}
~~~
雖然實現了功能,但是代碼比較長,但是如果你用Guava去實現同樣的功能,你會發現你的代碼一下子變少了。Guava提供了下面的結構
~~~
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
Multimap<K, V> myMultimap = ArrayListMultimap.create();
~~~
從名字可以看出,Multimap可以存放的key值是不唯一的,Multimap并沒有實現 Map 的接口,所以不需要達到鍵唯一的要求。如果存放了key一樣的元素,Multimap并不會覆蓋以前相同的key元素,而是加進去了。結果有點像{k1=[v1, v2, v3], k2=[v7, v8],….}其中v1, v2, v3對應的key都是k1,而如果是Map,則它的結果有點像{k1=v1, k2=v2,…}看到區別了吧?那么,用Multimap實現上面同樣的功能代碼有點像
~~~
Multimap<String, Person> myMultimap = ArrayListMultimap.create();
for (Person person : personList) {
String sex = person.getSex();
myMultimap.put(sex, person);
}
Map<String, Collection<Person>> map1 = myMultimap.asMap();
for (Entry<String, Collection<Person>> entry : map1.entrySet()) {
String key = entry.getKey();
System.out.println(key + "\t" + entry.getValue());
}
~~~
看到了吧,代碼簡單多了吧!這里有一點你可能會疑惑,就是為何get方法返回的是一個Collection而不是list,這是因為前者會更加有用。如果你需要基于multimap直接操作list或者set,那么可以在定義類型的時候使用子類名稱:ListMultimap,SetMultimap和SortedSetMultimap。例如:
~~~
ListMutlimap<String,Person> myMutlimap = ArrayListMultimap.create();
// Returns a List, not a Collection.
List<Person> myValues = myMutlimap.get("myKey");
~~~
這里需要再次強調的是,Multimap不是Map(Multimap Is Not A Map)!
一個Multimap<K, V>不是一個Map<K, Collection<V>>, 雖然我們可以利用Map<K, Collection<V>>來實現Multimap<K, V>,即使如此,它們之間還是有區別的:
1. Multimap.get(key) 總是返回一個unll值(可能是一個空的collection);
1. 可以利用asMap()方法來得到一個?Map<K, Collection<V>>類型的數據(或者利用ListMultimap中的靜態方法Multimaps.asMap()得到一個Map<K, List<V>類型的數據;?SetMultimap和SortedSetMultimap也類似);
1. Multimap.containsKey(key)只有在這個key和一個或者多個元素相關聯的時候才會返回true,如果這個key在刪除之前和一個或者多個元素相關聯則函數將會返回false;
1. Multimap.entries()返回Multimap所有實體的所有key值;
1. Multimap.size()返回在Multimap中存放的所有實體的數量,而不是不同keys的數量。我們可以利用Multimap.keySet().size()得到Multimap中所有不同keys的數量。
(完)
轉載請注明: 轉載自[過往記憶(http://www.iteblog.com/)](http://www.iteblog.com/)
本文鏈接地址:?[Guava學習之Multimap(http://www.iteblog.com/archives/488)](http://www.iteblog.com/archives/488)